gRPC客户端创建和调用原理解析(5)

gRPC客户端创建和调用原理解析

2.2. NettyClientHandler功能和源码分析

NettyClientHandler继承自Netty的Http2ConnectionHandler,是gRPC接收和发送HTTP/2消息的关键实现类,也是gRPC和Netty的交互桥梁,它的主要功能如下所示:

发送各种协议消息给gRPC服务端

接收gRPC服务端返回的应答消息头、消息体和其它协议消息

处理HTTP/2协议相关的指令,例如StreamError、ConnectionError等。

协议消息的发送:无论是业务请求消息,还是协议指令消息,都统一封装成QueuedCommand,由NettyClientHandler拦截并处理,相关代码如下所示:

(点击放大图像)

gRPC客户端创建和调用原理解析

协议消息的接收:NettyClientHandler通过向Http2ConnectionDecoder注册FrameListener来监听RPC响应消息和协议指令消息,相关接口如下:

(点击放大图像)

gRPC客户端创建和调用原理解析

FrameListener回调NettyClientHandler的相关方法,实现协议消息的接收和处理:

(点击放大图像)

gRPC客户端创建和调用原理解析

需要指出的是,NettyClientHandler并没有实现所有的回调接口,对于需要特殊处理的几个方法进行了重载,例如onDataRead和onHeadersRead。

2.3. ProtocolNegotiator功能和源码分析

ProtocolNegotiator用于HTTP/2连接创建的协商,gRPC支持三种策略并有三个实现子类:

(点击放大图像)

gRPC客户端创建和调用原理解析

gRPC的ProtocolNegotiator实现类完全遵循HTTP/2相关规范,以PlaintextUpgradeNegotiator为例,通过设置Http2ClientUpgradeCodec,用于101协商和协议升级,相关代码如下所示:

(点击放大图像)

gRPC客户端创建和调用原理解析

2.4. LoadBalancer功能和源码分析

LoadBalancer负责客户端负载均衡,它是个抽象类,gRPC框架的使用者可以通过继承的方式进行扩展。

gRPC当前已经支持PickFirstBalancer和RoundRobinLoadBalancer两种负载均衡策略,未来不排除会提供更多的策略。

以RoundRobinLoadBalancer为例,它的工作原理如下:根据PickSubchannelArgs来选择一个Subchannel:

(点击放大图像)

gRPC客户端创建和调用原理解析

再看下Subchannel的选择算法:

(点击放大图像)

gRPC客户端创建和调用原理解析

即通过顺序的方式从服务端列表中获取一个Subchannel。

如果用户需要定制负载均衡策略,则可以在RPC调用时,使用如下代码:

(点击放大图像)

2.5. ClientCalls功能和源码分析

ClientCalls提供了各种RPC调用方式,包括同步、异步、Streaming和Unary方式等,相关方法如下所示:

(点击放大图像)

gRPC客户端创建和调用原理解析

下面一起看下RPC请求消息的发送和应答接收相关代码。

2.5.1. RPC请求调用源码分析

请求调用主要有两步:请求Frame构造和Frame发送,请求Frame构造代码如下所示:

(点击放大图像)

gRPC客户端创建和调用原理解析

使用PB对请求消息做序列化,生成InputStream,构造请求Frame:

(点击放大图像)

gRPC客户端创建和调用原理解析

Frame发送代码如下所示:

(点击放大图像)

gRPC客户端创建和调用原理解析

NettyClientHandler接收到发送事件之后,调用Http2ConnectionEncoder将Frame写入Netty HTTP/2协议栈:

(点击放大图像)

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/13469.html