使用envoy proxy对grpc服务进行负载平衡

简介

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连接,所有请求都被多路复用,意味着多个请求可以在任何时间点在同一连接上处于活动状态。这减少了连接管理开销,但也意味着连接级的均衡没有作用。一旦建立连接,就不再需要进行平衡。所有的请求都将固定到单个目标实例上,如下所示:
使用envoy proxy对grpc服务进行负载平衡

  • 为什么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连接,并在这些连接之间均衡请求,如下所示:
使用envoy proxy对grpc服务进行负载平衡
在网络方面,这意味着我们需要在L5/L7而不是L3/L4作出决策,即我们需要了解通过TCP连接发送的协议。有几种选择:

  1. 我们的应用程序代码可以手动维护自己的目标负载均衡池,然后配置我们的grpc客户端以使用此负载均衡池。这种方法为我们提供了最大程度的控制,但在kubernetes这样的环境中它可能非常复杂,随着kubernetes重新调度pod,池会随着时间的推移而变化。我们的应用程序必须观察kubernetes API并使其与pod保持同步。
  2. 在Kubernetes中,我们可以将我们的应用程序部署为headless服务,在这种情况下,kubernetes将在服务的DNS中创建多个A记录。如果我们的grpc客户端足够先进,它可以自动维护这些DNS的负载均衡池。但是这种方法将我们限制在某些grpc客户端,并且很少只使用headless服务。
  3. 使用轻量级代理,也就是本文使用的方式
  • 使用哪一个proxy

Nginx-ingress vs kong vs traefik vs haproxy …中比对了8个 apigateway 项目

使用envoy proxy对grpc服务进行负载平衡

从中可以看出数据平面以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就可以了,我们的部署像这样:

使用envoy proxy对grpc服务进行负载平衡

部署grpc服务

部署envoy服务

grpc负载均衡的其他方式

参考

  1. 使用 Envoy Proxy 对 GKE 上的 gRPC 服务进行负载平衡
  2. gRPC Load Balancing on Kubernetes without Tears
  3. gRPC Load Balancing inside Kubernetes
  4. 基于Envoy的ApiGateway/Ingress Controller项目梳理(总结)
  5. 8款开源的Kubernetes Ingress Controller/API Gateway推荐
  6. Benchmarking 5 Popular Load Balancers: Nginx, HAProxy, Envoy, Traefik, and ALB
  7. envoy BACKPRESSURE