为什么 grpc 中的 "loadBalancingPolicy“ must be used when "healthCheckConfig"

why the "loadBalancingPolicy“ must be used when "healthCheckConfig" in grpc

代码文件是: clientserver

有疑问的代码:

var serviceConfig = `{
    "loadBalancingPolicy": "round_robin",
    "healthCheckConfig": {
        "serviceName": ""
    }
}`

测试步骤:

1.Run只有一台服务器和一台客户端

2.When 使用“loadBalancingPolicy”:“round_robin”,客户端可以检测到服务器的“状态=NOT_SERVING”

3.When "loadBalancingPolicy": "round_robin"被删除,或者使用"pick_first",服务器的"status=NOT_SERVING"不能在客户端检测到

当有多个服务器地址时健康检查有意义。如果只有一个地址,则无需检查健康状况。所以负载均衡策略round_robin与健康检查一起工作。

round_robin会检查健康状态,所以会陆续向READY地址发送请求。

pick_first策略不支持健康检查,所以它将使用第一个成功连接的服务器。因此,任何请求都只会使用指定地址。

您可以阅读LB Policies Can Disable Health Checking When Needed中的健康检查和负载均衡策略文档。

为了调试客户端和服务器,您可以添加环境变量 GRPC_GO_LOG_SEVERITY_LEVEL=infoGRPC_GO_LOG_VERBOSITY_LEVEL=99 以获得传输和连接事件的更多细节。

仔细阅读源码,明白了内部实现

  1. pick_first
  • 它自己实现了“balancer.Builder”和“balancer.Balancer”。
  • "ResolverState.Addresses"只会创建一个SubConn,SubConn中有一个addrConn,用第一个addr创建ClientTransport。
  • Returns 每次调用 Pick() 时固定的“balancer.PickResult”。
  1. round_robin
  • 通过“base.NewBalancerBuilder()”传入参数“HealthCheck: true”和returnbaseBuilder作为Builder。
  • “ResolverState.Addresses”的每个地址都会创建一个对应的 SubConn。
  • 每次调用 Pick() 时,更改内部下一个值,从“[]balancer.SubConn”获取它,并且 return 一个新的“balancer.PickResult”。