gRPC 连接池的一种实现方案
Google远程过程调用(Google Remote Procedure Call,gRPC)是基于HTTP 2.0传输层协议承载的高性能开源 RPC 软件框架,为管理和配置网络设备提供了一种 API 接口设计的方法。gRPC提供了多种编程语言,如C、Java、golong、python等。 gRPC可以作为数据传输协议与Telemetry技术配合使用,可实时、高速、精确的监控网络设备的运行状态。此外,网络设备提供了一种基于 gRPC 方式来管理设备的方法,包括配置、查询和能力获取三种方法。这些方法是通过设备和采集器对接,实现采集设备数据的功能。
本文将详细说明在生产环境已经在使用的一种 gRPC 连接池实现方案,它有一个前提是对 gRPC 的使用已经引入了管理者角色(如 go-micro 框架),而不是完全使用 gRPC 框架管理连接。当然,小编也基于 gRPC 的 picker 等实现了原生 gRPC 的连接池管理。
Go-micro 早期版本,本质上是使用了 gRPC 的 transport,而且将 HTTP2.0 的能力退化成了普通的 TCP 连接,每个连接同一时刻只能处理一个请求,并发高的系统对于资源的开销也明显加大。本文的方案就是针对此进行的优化。
整体思路
go-micro 每个请求都会向 manager 获取一个连接,然后进行 invoke 操作。这让我们的优化目标非常明确:如何从 manager 中拿出重复使用,且有效的连接?
查找连接的整体思路为:
- 按条件查找有效连接,条件后续介绍;
- 如果找到有效连接则直接返回;
- 如果没有找到连接则开始争抢创建新连接的门票,防止连接创建过多;
- 抢到创建连接门票的进行二次 check,因为此时可能已经有返还使用的连接了;
- 如果二次 check 失败则创建新连接并返回连接,此时可考虑配合创建 gRPC 参数是 block 还是非 block 来决定是否返回门票。

查找连接
从连接中找到状态有效的连接:
连接池未满状态下,连接上的请求计数小于 8(可为其它值),如果连接池已经满,则无此限制;要注意的是 gRPC 有流上限,所以有可能出错原因不是连接池问题,而是 gRPC 限制。
连接未被其它请求置为无效状态;
连接复用,连接中任何一个请求失败都会主动设置当前连接为无效状态,并从连接管理数组中移除。
没有直接删除、关闭连接,而是使用引用计数的形式,让最后一个请求来处理连接。
连接在时效内;
找到有效连接后,增加引用计数并返回;
找到有效连接后,修改连接所在位置,参与下一次轮询。
1 |
|
原生 gRPC 复制多份连接
对于原生 gRPC,是基于不同 node 创建了单独的连接,但是可以修改连接中的 attribute 属性来为每个 node 复制多条连接,防止一条连接上的请求过多。
附
https://github.com/gowins/go-kit
