gRPC 负载均衡
Table of Contents
1. 常用负载均衡方法
1.1. 代理模式
在客户端和服务器之间提供一层服务转发代理,代理需要拥有将 RPC 的请求和响应临时副本,会消耗更多的资源。 代理模式会增加了 RPC 的延迟。在代理大量的服务(比如存储),会被任务效率低下。
1.2. 客户端的均衡
把负载均衡的逻辑放在客户端中。客户端自己实现负载均衡策略(比如:轮询,随机分发等)来选择一个后端服务。在这种情况下,客户端通过 name resolution 系统 中拉取服务器列表。
这种方法的缺点之一是要书写多语言,多版本的负载均衡器和维护。这些策略比较复杂。一些算法需要服务器和客户端通信来除了满足用户需要请求的 RPC 调用之外, 还需要额外的支持 RPC 以获得后端服务的运行状态和加载信息等。
总之,会增大客户端的代码复杂度。
1.3. 额外的负载均衡服务
客户端向负载均衡服务发出请求,负载均衡服务负责维护服务器列表的维护,以及实现各种复杂的负载均衡策略,而且通过健康检测和服务器的负载来合理的处理服务器可用性。
这种情况下,客户端和服务都很轻松。
第一种代理模式和第三种额外的负载均衡服务,我理解都是在客户端和服务器之间加了一个中间层,都可以称之为代理。只不过实现手段不一样(基于的网络协议)不同。 第一种是同等协议的转发,比如 HTTP 请求转发;而第三种是基于底层的网络协议转发,以节省资源浪费。 第三种的例子是 nginx,kubernetes 中的 services,或者 service mash 中的 sidecar。
2. gRPC Load Balancing 2017
2.1. 代理的负载均衡器选项
代理分为:L3/L4(传输层)代理或者 L7(应用层)代理。
- 在传输层的代理中,服务器终止 TCP 连接,然后在后端列表中再选一个。
- 应用层(HTTP/2 和 gRPC 桢)只需要简单在客户端连接和后端连接之间复制即可。
相比 L7,L3/L4 做的事情少,延迟短,消耗更少的资源。在 L7 中,LB 终止并解析 HTTP/2 协议。LB 可以根据请求内容分配后端,比如根据头部的 Cookie 值与特定的后端关联, 因此同一个会话的所有请求全部会转发给同一个后端。一旦 LB 选择了一个后端,它会创建一个新的 HTTP/2 连接,然后把客户端收到的 HTTP/2 流转发到所选的后端。使用 HTTP/2 LB 可以在多个后端之间分配来自同一个客户端的流。
也就是说,L7 是会同时建立一个与客户端和服务器的流,然后做请求,响应复制转发。
选择 L3/L4 还是 L7?
用户案例 | 推荐 |
---|---|
RPC 在大量连接中负载变化很大 | L7 |
存储或者计算亲和力很重要 | L7,并使用 cookie 或者类似的东西进行后端请求矫正 |
最大限度的减少代理中的资源利用率(比功能更重要) | L3/L4 |
低延迟容忍 | L3/L4 |
2.2. 客户端和服务器的负载均衡对比
(略),一般不会选择客户端。
2.3. 最佳实践
场景 1
- 客户端和服务器之间流量非常大
- 客户端可以被信赖
推荐:
- 客户端侧(重)的负载均衡
- 带 ZooKeeper/Etcd/Consul/Eureka 的客户端,ZooKeeper 范例
场景 2
- 传统逻辑 - 许多客户端连接到代理后面的服务
- 客户端和服务器之间需要信任边界
推荐:
- 负载均衡代理
- L3/L4 LB + GCLB(如果使用 GCP 的话)
- L3/L4 LB + haproxy - 配置文件
- nginx 不久会支持 事实上 nginx 1.13.10 已经支持了,https://www.nginx.com/blog/nginx-1-13-10-grpc 在这篇文章发布之后 2018.3
- 如果需要会话粘滞性 - 使用 Envoy 代理的 L7 LB
场景 3
- 微服务架构 - 数据中心中有 N 个 客户端,M 个服务器
- 极高的性能要求(低延迟、高流量)
- 客户端不受信任
推荐:
- 后备负载均衡
- 使用 gRPC-LB 协议的客户端 LB,Roll your own implementation (Q2’17), hosted gRPC-LB in the works
场景 4
- 已存在服务网格架构,使用 Linkerd 或者 Istio
推荐:
- Service Mesh
- 使用 Istio 或者 Envoy 内置的 LB
3. Nginx gRPC 支持
https://www.nginx.com/blog/nginx-1-13-10-grpc/
https://nginx.org/en/docs/http/ngx_http_grpc_module.html
Nginx 作为 client 和 server 之间的 proxy,跟之前支持 HTTP 和 TCP 一样,对 gRPC 支持已经比较完善了。