简介
grpc 是基于 HTTP/ 2 且与语言无关的开源 RPC 框架,它使用协议缓冲区实现高效的传输和快速序列化。受内部 Google RPC 框架 Stubby 启发,grpc 支持微服务之间以及移动客户端和 API 之间的低延迟通信。grpc 通过 HTTP/ 2 运行,与通过 HTTP/1.1 运行相比具有若干优点,例如高效的二进制编码显著降低序列化成本,通过单个连接复用请求和响应减少 TCP 管理开销,以及自动类型检查。但是 kubernetes 的默认负载平衡通常不能对 grpc 起到作用,需要添加其他 grpc 负载均衡服务。
- 为什么 grpc 需要特殊的负载均衡
因为 grpc 构建在 HTTP/ 2 上,而 HTTP/ 2 被设计为具有单个长期 TCP 连接,所有请求都被多路复用,意味着多个请求可以在任何时间点在同一连接上处于活动状态。这减少了连接管理开销,但也意味着连接级的均衡没有作用。一旦建立连接,就不再需要进行平衡。所有的请求都将固定到单个目标实例上,如下所示:
- 为什么 HTTP/1.1 不受影响
与 HTTP/ 2 相比,HTTP/1.1 不能复用请求,每个 TCP 连接一次只能激活一个 HTTP 请求。客户端发出请求,例如 GET/foo,然后等待服务器响应,在发生请求 - 响应周期里,不能在该连接上发出其他请求。通常,我们希望并行发出大量请求。因此,我们需要建立多个 HTTP/1.1 连接,并在所有这些连接中发出请求。此外,长期存在的 HTTP/1.1 连接会在一段时间后过期,并被客户端或服务器断开。这两个因素意味着 HTTP/1.1 请求通常在多个 TCP 连接之间循环,因此连接级均衡起作用。
- 如何对 grpc 进行负载均衡
由于我们无法在连接级别进行均衡,我们需要从连接均衡转向请求均衡。换句话说,我们需要打开到每个目标的 HTTP/ 2 连接,并在这些连接之间均衡请求,如下所示:
在网络方面,这意味着我们需要在 L5/L7 而不是 L3/L4 作出决策,即我们需要了解通过 TCP 连接发送的协议。有几种选择:
- 我们的应用程序代码可以手动维护自己的目标负载均衡池,然后配置我们的 grpc 客户端以使用此负载均衡池。这种方法为我们提供了最大程度的控制,但在 kubernetes 这样的环境中它可能非常复杂,随着 kubernetes 重新调度 pod,池会随着时间的推移而变化。我们的应用程序必须观察 kubernetes API 并使其与 pod 保持同步。
- 在 Kubernetes 中,我们可以将我们的应用程序部署为 headless 服务,在这种情况下,kubernetes 将在服务的 DNS 中创建多个 A 记录。如果我们的 grpc 客户端足够先进,它可以自动维护这些 DNS 的负载均衡池。但是这种方法将我们限制在某些 grpc 客户端,并且很少只使用 headless 服务。
- 使用轻量级代理,也就是本文使用的方式
- 使用哪一个 proxy
Nginx-ingress vs kong vs traefik vs haproxy …中比对了 8 个 apigateway 项目
从中可以看出数据平面以 nginx 和 envoy 为主,traefix 等少部分项目自己实现了数据面功能。Haproxy 和 Nginx 是经典的代理转发软件,应用广泛、性能好,但是它们诞生较早没有清晰的控制接口,只能通过重新加载配置文件的方式刷新配置。其中 Nginx 因为支持模块扩展,灵活性相对较高,kubernetes/ingress-nginx、kong 等项目使用 lua 模块,减少了配置加载次数或者为 nginx 开发了控制接口。
Envoy 诞生较晚,有完备的控制接口,正致力于成为数据平面的标准方案,应当作为首要选择。Haproxy 对新的场景和新的需求跟进缓慢,最先排除。Nginx 扩展性好、社区活跃,目前没有一个统一的控制接口,开源版本功能弱于收费版的 nginx-plus,可以选择。
从 apigateway 开源项目的数量来看,也是 envoy>nginx>haproxy,ambassador 详细介绍了选择 envoy 的心路历程。
从 benchmaking 可以看出 envoy 的性能表现最好。
本文需要的只是一个轻量级的 proxy,envoy 就可以了,我们的部署像这样:
部署 grpc 服务
部署 envoy 服务
grpc 负载均衡的其他方式
参考
- 使用 Envoy Proxy 对 GKE 上的 gRPC 服务进行负载平衡
- gRPC Load Balancing on Kubernetes without Tears
- gRPC Load Balancing inside Kubernetes
- 基于 Envoy 的 ApiGateway/Ingress Controller 项目梳理(总结)
- 8 款开源的 Kubernetes Ingress Controller/API Gateway 推荐
- Benchmarking 5 Popular Load Balancers: Nginx, HAProxy, Envoy, Traefik, and ALB