gRPC负载平衡

use*_*707 10 kubernetes google-kubernetes-engine grpc grpc-java

我已经阅读了https://github.com/grpc/grpc/blob/master/doc/load-balancing.md上的负载平衡页面,但仍然对后端GRPC之间正确的负载均衡方法感到困惑实例.我们正在部署多个gRPC"微服务"实例,并希望我们的其他gRPC客户端能够在它们之间进行路由.我们将这些作为pods部署在kubernetes(实际上是Google Container Engine)中.

任何人都可以解释在gRPC服务器之间加载平衡gRPC客户端请求的"推荐"方法吗?似乎客户需要了解端点 - 是否不可能利用Container Engine中的内置LoadBalancer来提供帮助?

Dav*_*tas 11

我不能谈论kubernetes,但是关于gRPC负载平衡,基本上有两种方法:

  1. 对于简单的用例,您可以在针对给定名称返回的地址列表(即,为service.foo.com返回的IP列表)上启用循环.这样做的方法取决于语言.对于C++,您可以使用grpc::ChannelArguments::SetLoadBalancingPolicyName"round_robin"作为参数(将来也可以通过" 服务配置 " 进行选择,但是如何在DNS记录中对该配置进行编码的设计尚未最终确定).
  2. 使用grpclb协议.这适用于更复杂的部署.此功能需要c-ares DNS解析器,#11237引入(此PR非常接近合并).这是使grpclb在开源中工作所缺少的部分.特别是:
    • 看看这个文件.它会检查控制哪些地址被标记为平衡器所需的DNS配置更改.它目前是一个"提案",很快就会升级为文档.它可以非常权威地使用,它是#11237为平衡器发现实现的.
    • 编写实现负载均衡器协议的常规gRPC服务器(使用任何语言).这是在DNS记录中作为平衡器标记的服务器(如前面提到的文档所述),客户端的grpclb将与之通信以获取后端地址列表(所谓的server_lists).您可以根据需要将此平衡器内的逻辑简单或复杂化.
    • 创建通道时,客户端将使用平衡器的DNS名称.另请注意,您的平衡器DNS名称可能指向多个地址.如果其中一个或多个被标记为平衡器,则将使用grpclb.如果有多个平衡器,将会选择哪个平衡器?客户端连接的第一个.

如果您有任何疑问,请告诉我.

  • 尼尔,试试 `channel = grpc.insecure_channel("my.grpc.server.com", ("grpc.lb_policy_name", "round_robin"))` (2认同)

Sam*_*dra 5

对于 grpc 服务器之间的负载平衡,kubernates 默认负载平衡无济于事,因为它是 L4 负载平衡器。您将需要 L7 负载平衡器。

为什么是L7?

grpc 使用 http2,其中连接是持久的,请求将通过同一连接发送。L4 负载平衡器将使用 tcp 连接进行负载平衡,但您需要在请求级别进行负载平衡,因此我们需要 L7 负载平衡器。尤其是在 grpc 服务器之间进行通信时。

有几个选项,您可以Linkered/Envoy为此使用它们,它们与 kubernates 配合良好,并且还提供良好的服务网格。

要将您的服务暴露给外部工作,您可以使用 nghttpx 和 nghttpx Ingress 控制器。

您也可以使用客户端负载平衡,但我认为这没有什么好处。


Mar*_*kNS 0

您可能想查看nghttpxnghttpx Ingress 控制器项目。这些项目使得对 HTTP/2 流执行 L7 负载平衡成为可能。

另请参阅https://cloud.google.com/endpoints/docs/architecture-overview,了解有关 Google Cloud Platform 中捆绑的端点管理的一些信息。