gRPC 负载均衡
范围
本文档解释了gRPC中负载均衡的设计。
背景
gRPC中的负载均衡是基于每次调用进行的,并不是基于每次连接的。换句话说,即使所有请求都来自同一客户端,我们依然希望他们在所有的服务端中进行负载均衡。
架构
Overview
gRPC客户端支持允许实现负载均衡策略并将其插入gRPC的API。这个负载均衡策略主要负责:
- 从resolver接收更新配置和服务器地址列表
- 为服务器地址创建子通道,并管理他们的连接行为
- 设置通道的整体连接状态(通常通过聚合子通道的连接状态来计算)
- 为通道上发送的每个RPC,确定在哪个子通道上发送RPC
gRPC提供了一些负载均衡策略。最值得注意的是pick_first
(默认)、round_robin
和grpclb
。也一些额外的策略支持xDS,但是他们当前并没有直接配置。
Workflow
负载平衡策略适合 gRPC 客户端工作流,介于名称解析和与服务器的连接之间。以下是它的工作原理:
- 再开始的时候,gRPC客户端对服务名发起名称解析请求。这个服务名会解析成一个ip地址列表,一个服务配置,指示使用哪个客户端负载均衡策略(例如round_robin或grpclb),并提供该策略的配置和一组属性(C-core中的通道args)。
- 客户端实例化负载平衡策略并将其配置从服务配置、IP 地址列表和属性传递给它。
- 负载平衡策略为服务器的 IP 地址创建一组子通道(可能与解析器返回的 IP 地址不同;见下文)。它还监视子通道的连接状态并决定每个子通道何时应尝试连接。
- 对于每个发送的 RPC,负载平衡策略决定 RPC 应该发送到哪个子通道(即哪个服务器)。
有关 grpclb 的更多信息,请参见下文。
负载均衡策略
pick_first
如果服务配置没有指定其他策略的情况下,pick_first是默认的LB策略。它不需要任何配置。
这个策略会从解析器取到地址列表。它尝试按顺序一次连接一个地址,直到找到一个可访问的地址。如果没有可访问的,它在尝试重新连接时将通道的状态设置为 TRANSIENT_FAILURE。对重复的连接尝试应当需要适当的backoff。
如果能连接到其中一个地址,它会设置通道的状态为READY,并且通道上的所有RPC都会从这个地址发送。如果这个地址的连接在之后断开了,pick_first
策略会把通道置于IDLE状态,并且它不会尝试重新连接,直到应用程序请求它这样做(通过通道的连接状态 API 或通过发送 RPC)。
round_robin
此 LB 策略是通过服务配置选择的。它不需要任何配置。
这个策略会从解析器取到地址列表。它为每个地址创建一个子通道,并持续监控子通道的连接状态。每当子通道断开连接时,round_robin
策略将要求它重新连接,并带有适当的连接backoff。
这个策略通过子通道状态的聚合来设置通道的连接状态:
- 如果任何一个子通道是READY状态,那么这个主通道的状态就是READY。
- 如果任何一个子通道是CONNECTING状态,那么这个主通道的状态就是CONNECTING。
- 如果任何一个子通道是IDLE状态,那么这个主通道的状态就是IDLE。
- 如果所有子通道是TRANSIENT_FAILURE状态,那么这个主通道的状态才是TRANSIENT_FAILURE。
注意:当给定子通道报告 TRANSIENT_FAILURE 时,它被认为仍处于 TRANSIENT_FAILURE 中,直到它成功重新连接并报告 READY。特别是,我们忽略了从 TRANSIENT_FAILURE 到 CONNECTING 的转换。
当在通道上发送RPC时,round_robin
策略将遍历当前处于READY状态的所有子通道,将每个连续的RPC发送到列表中的下一个连续的子通道,在需要时环绕到列表的开始。
grpclb
(这个策略已被废弃,推荐使用xDS代替)
此 LB 策略最初旨在作为 gRPC 用于负载平衡的主要可扩展性机制。其目的是,与其直接在客户端中添加新的 LB 策略,客户端可以只实现简单的算法,如 round_robin,而任何更复杂的算法都将由后备负载均衡器提供。
客户端依赖负载均衡器来提供配置和客户端应该向其发送请求的服务器地址列表。平衡器根据需要更新服务器列表以平衡负载以及处理服务器不可用或健康问题。负载均衡器将做出任何必要的复杂决策并通知客户端。负载均衡器可以与后端服务器通信以收集负载和健康信息。
grpclb 策略使用解析器返回的地址(如果有)作为备用地址,当它与平衡器失去联系时使用这些地址。
grpclb 策略通过解析器返回的属性获取要与之通信的平衡器的地址列表。