python - gRPC 客户端负载均衡

标签 python http dns kubernetes grpc

我在 kubernetes pod 中使用带有 Python 的 gRPC 作为客户端/服务器... 我希望能够启动多个相同类型的 pod(gRPC 服务器)并让客户端(随机)连接到它们。

我分派(dispatch)了 10 个服务器 pod 并设置了一个“服务”来定位它们。然后,在客户端中,我连接到服务的 DNS 名称——这意味着 kubernetes 应该进行负载平衡并将我定向到一个随机服务器 pod。 实际上,客户端调用 gRPC 函数(运行良好)但是当我查看日志时,我发现所有调用都转到同一个服务器 pod。

我假设客户端正在执行某种 DNS 缓存,这会导致所有调用都发送到同一台服务器。是这样吗?无论如何禁用它并设置相同的 stub 客户端进行"new"调用并在每次调用时通过 DNS 获取新的 ip?

我知道如果它每次都查询 DNS 服务器可能会导致开销,但目前分配负载对我来说更为重要。

最佳答案

让我借此机会通过描述事情应该如何运作来回答。

客户端 LB 在 gRPC C 核心(除了 Java 和 Go 风格或 gRPC 之外的所有基础)中的工作方式如下(可以找到权威文档 here ):

客户端 LB 故意保持简单和“愚蠢”。我们选择实现复杂 LB 策略的方式是通过外部 LB 服务器(如上述文档中所述)。您不关心这种情况。相反,您只是创建一个 channel ,它将使用(默认)优先选择 LB 策略。

LB 策略的输入是已解析地址的列表。使用 DNS 时,如果 foo.com 解析为 [10.0.0.1, 10.0.0.2, 10.0.0.3, 10.0.0.4],该策略将尝试与所有这些建立连接。第一个成功连接的将成为选中的那个直到它断开连接。因此得名“先挑”。更长的名称可能是“首先选择并尽可能长时间地使用它”,但这导致了一个非常长的文件名 :)。如果/当挑选一个人断开连接时,选择优先的策略将转移到返回下一个成功连接的地址(内部称为“连接的子 channel ”),如果有的话。再一次,只要它保持连接,它就会继续选择这个连接的子 channel 。如果所有这些都失败,则调用将失败。

这里的问题是 DNS 解析本质上是基于拉取的,仅在 1) channel 创建时和 2) 在所选连接的子 channel 断开连接时触发。

截至目前,一个 hacky 解决方案是为每个请求创建一个新 channel (效率非常低,但根据您的设置它可以解决问题)。

鉴于 2017 年第一季度即将发生的变化(参见 https://github.com/grpc/grpc/issues/7818),客户将可以选择不同的 LB 政策,即 Round Robin。此外,我们可能会考虑在该客户端配置中引入一个“随机化”位,这将在对地址进行循环之前对地址进行洗牌,从而有效地实现您的意图。

关于python - gRPC 客户端负载均衡,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39643841/

相关文章:

DNS 答案的安全性

ssl - 为帐户提供专用 IP 后文档根目录错误

python - 如何从 gitlab CI 工件文件夹发布覆盖率报告?

python - 装饰器 "object is not callable"

python - Pandas - 如果满足条件则更新列

http - 使用http协议(protocol)发送电子邮件?

http - 我在 Glassfish 3.1 上的应用程序不会执行客户端身份验证

python - 如何解释python3的帮助输出?

iphone - MPMoviePlayerController 播放 YouTube 视频

dns - Docker:为什么/etc/resolv.conf不可读?破坏 DNS