gRPC Transport
Transport 分为 ClientTransport 和 ServerTransport,分别用于客户端和服务端

ClientTransport
ClientTransport 与真正的 IP 地址是一一对应的,用于建立连接,创建流
实现
ClientTransport 有多个继承接口和实现类:
- 支持失败的实现类
FailingClientTransport,客户端启动时创建的流会快速失败 - 支持生命周期管理的接口
ManagedClientTransport- 支持延迟处理的实现类
DelayedClientTransport - 基于连接的接口
ConnectionClientTransport- 基于 Netty 实现的
NettyClientTransport - 基于 OkHttp 实现的
OkHttpClientTransport - 用于进程内处理请求
InProcessTransport - 支持代理的抽象实现类
ForwardingConnectionClientTransport- 支持授权检查的实现类
CallCredentialsApplyingTransportFactory - 用于统计的
CallTracingTransport
- 支持授权检查的实现类
- 基于 Netty 实现的
- 支持延迟处理的实现类
方法
- ClientTransport#newStream
创建新的流,用于给远程服务端发送消息
1 | ClientStream newStream(MethodDescriptor<?, ?> method, Metadata headers, CallOptions callOptions); |
- ClientTransport#ping
ping 远程的端点,当收到 ack 之后,会使用所给的 Executor 执行回调
1 | void ping(PingCallback callback, Executor executor); |
- ManagedClientTransport#start
启动 Transport,尝试建立连接,并启动监听器
1 | Runnable start(Listener listener); |
监听器
Transport 的 Listener 用于监听 Transport 事件,进行相应的处理
- 监听就绪事件
1 | void transportReady(); |
- 监听使用中事件
1 | void transportInUse(boolean inUse); |
- 监听关闭事件
1 | void transportShutdown(Status s); |
- 监听终止事件
1 | void transportTerminated(); |
ClientTransport 流程
Transport 在 Channel 退出空闲模式时会被创建,然后通过 start 方法启动,建立连接,当连接成功后触发 ready 回调,然后更新 LB 状态为 READY,然后可以执行发送请求到服务端
1. 创建 Transport
有两个地方可以创建 Transport:
- LB 通过
handleResolvedAddresses处理地址时通过ManagedChannelImpl.SubchannelImpl#requestConnection建立连接,会创建 Transport ClientCallImpl#start时,通过ClientTransportProvider#get方法获取 Transport
这两个方法最终在 InternalSubchannel#obtainActiveTransport 中调用 startNewTransport 执行创建
启动 Transport
io.grpc.internal.InternalSubchannel#startNewTransport
1 | private void startNewTransport() { |
执行创建 Transport
io.grpc.netty.NettyChannelBuilder.NettyTransportFactory#newClientTransport
1 | public ConnectionClientTransport newClientTransport(SocketAddress serverAddress, |
2. 启动监听器,建立连接
io.grpc.netty.NettyClientTransport#start
1 | public Runnable start(Listener transportListener) { |
触发 ready 回调
当 Netty 的 Handler 第一次接收到返回的消息时触发回调
io.grpc.netty.NettyClientHandler.FrameListener#onSettingsRead
1 | public void onSettingsRead(ChannelHandlerContext ctx, Http2Settings settings) { |
io.grpc.netty.ClientTransportLifecycleManager#notifyReady
1 | public void notifyReady() { |
io.grpc.internal.InternalSubchannel.TransportListener#transportReady
1 | public void transportReady() { |
最终由 LoadBalancer 处理,将 Subchannel 的连接状态改为 READY,返回非空的 PickResult,这样就可以执行向 Server 端发送的请求