这是一篇翻译+转载图+自我理解实践。


译文:gRPC中的负载均衡

本文档介绍了gRPC中负载均衡的设计

背景

每次调用负载均衡

值得注意的是,gRPC 内的负载均衡是在每个调用的基础上发生的,而不是基于每个连接的。

换句话说,即使所有请求都来自单个客户端,我们仍然希望它们在所有服务器之间进行负载均衡。

负载均衡的方法

在深入任何 gRPC 细节之前,我们将探索一些常用的方法来实现负载均衡。

代理模型(集中式LB(Proxy Model))

使用代理提供可靠的可信客户端,可以向负载均衡系统报告负载。代理通常需要更多资源才能运行,因为它们具有 RPC 请求和响应的临时副本。

此模型还会增加 RPC 的延迟。在考虑诸如存储之类的请求重型服务时,代理模型被认为是低效的。

客户端负载均衡方式(进程内LB(Balancing-aware Client))

这个较重的客户端将更多的负载均衡逻辑放在客户端中。例如,客户端可以包含许多用于从列表中选择服务器的负载均衡策略(循环,随机等)。在此模型中,服务器列表将在客户端中静态配置,由名称解析系统提供,外部负载均衡器等。在任何情况下,客户端都负责从列表中选择首选服务器。

这种方法的缺点之一是以多种语言和/或客户端版本编写和维护负载均衡策略。这些策略可能相当复杂。一些算法还需要客户端到服务器通信,因此除了为用户请求发送 RPC 之外,客户端还需要更重,以支持其他 RPC 来获取运行状况或负载信息。

它还会使客户端的代码大大复杂化:新设计隐藏了多层负载均衡的复杂性,并将其作为服务器的简单列表呈现给客户端。

外部负载均衡服务(独立 LB 进程(External Load Balancing Service))

客户端负载均衡代码保持简单和可移植,实现用于服务器选择的众所周知的算法(例如,循环)。 复杂的负载均衡算法由负载均衡器提供。 客户端依赖负载均衡器来提供负载均衡配置以及客户端应向其发送请求的服务器列表。 平衡器根据需要更新服务器列表以平衡负载以及处理服务器不可用或健康问题。 负载均衡器将做出任何必要的复杂决策并通知客户。 负载均衡器可以与后端服务器通信以收集负载和健康信息。

要求

简单的 API 和客户端

gRPC 客户端负载均衡代码必须简单且可移植。 客户端应仅包含用于服务器选择的简单算法(例如,循环)。 对于复杂算法,客户端应依赖负载均衡器来提供负载均衡配置以及客户端应向其发送请求的服务器列表。 平衡器将根据需要更新服务器列表,以平衡负载以及处理服务器不可用或健康问题。 负载均衡器将做出任何必要的复杂决策并通知客户。 负载均衡器可以与后端服务器通信以收集负载和健康信息。

安全

负载均衡器可能与实际的服务器后端分开,并且负载均衡器的危害只会导致负载均衡功能受到损害。 换句话说,受损的负载均衡器不应该导致客户端信任(可能是恶意的)后端服务器,而不是在没有负载均衡的可比情况下。

架构

概览

gRPC 中负载均衡的主要机制是外部负载均衡,其中外部负载均衡器为简单客户端提供最新的服务器列表。

gRPC 客户端确实支持内置负载均衡策略的 API。 但是,只有少数这些(其中一个是实现外部负载均衡的 grpclb 策略),并且不鼓励用户尝试通过添加更多来扩展 gRPC。 相反,应在外部负载均衡器中实施新的负载均衡策略。

工作流

负载均衡策略适用于命名解析和与服务器的连接之间的 gRPC 客户端工作流。

gRPC 开源组件官方并未直接提供服务注册与发现的功能实现,但其设计文档已提供实现的思路,并在不同语言的 gRPC 代码 API 中已提供了命名解析和负载均衡接口供扩展。

以下是它的工作原理:

  1. 启动时,gRPC 客户端会为服务器名称发出名称解析请求。该名称将解析为一个或多个 IP 地址,每个 IP 地址将指示它是服务器地址还是负载均衡器地址,以及指示要使用哪个客户端负载均衡策略的服务配置(例如,round_robin 或 grpclb)。

  2. 客户端实例化负载均衡策略。

    • 注意:如果解析程序返回的任何一个地址是均衡器地址,则无论服务配置请求了什么负载均衡策略,客户端都将使用 grpclb 策略。否则,客户端将使用服务配置请求的负载均衡策略。如果服务配置未请求负载均衡策略,则客户端将默认使用选择第一个可用服务器地址的策略。
  3. 负载均衡策略为每个服务器地址创建一个子通道。

    • 对于除 grpclb 之外的所有策略,这意味着解析器返回的每个地址都有一个子通道。请注意,这些策略会忽略解析程序返回的任何均衡器地址。
    • 对于grpclb策略,工作流程如下: a. 该策略打开一个流到解析器返回的平衡器地址之一。它要求平衡器将服务器地址用于客户端最初请求的服务器名称(即,最初传递给名称解析器的服务器名称)。 + 注意:在 grpclb 策略中,解析器返回的非平衡器地址用作后备,以防在启动 LB 策略时无法联系到平衡器。 b. 如果负载均衡器的配置需要该信息,则负载均衡器指向客户端的 gRPC 服务器可以向负载均衡器报告负载。 c. 负载均衡器将服务器列表返回给 gRPC 客户端的 grpclb 策略。然后,grpclb 策略将为列表中的每个服务器创建一个子通道。
  4. 对于发送的每个 RPC ,负载平衡策略决定应将 RPC 发送到哪个子通道(即哪个服务器)。

    • 对于 grpclb 策略,客户端将按负载均衡器返回的顺序向服务器发送请求。如果服务器列表为空,则调用将阻塞,直到收到非空的调用。

参考资料

  1. gRPC load-balancing
  2. gRPC服务发现&负载均衡
  3. https://github.com/smallnest/grpc-examples
  4. https://colobu.com/2017/04/06/dive-into-gRPC-streaming/
  5. https://colobu.com/2017/04/17/dive-into-gRPC-interceptor/

茶歇驿站

一个可以让你停下来看一看,在茶歇之余给你帮助的小站,这里的内容主要是后端技术,个人管理,团队管理,以及其他个人杂想。