目录
RPC管道处理TransportChannelHandler
接着【Spark内核源码】内置的RPC框架,Spark的通信兵(一) 接着分析
RPC管道处理TransportChannelHandler
TransportContext最后一个作用就是使用org.apache.spark.network.server.TransportChannelHandler设置Netty Channel pipelines(Netty的通信管道)。
在TransportClientFactory的createClient方法和TransportServer的init方法中都执行了初始化管道方法,也就是TransportContext中的initializePipeline方法。


initializePipeline方法的代码如下:
public TransportChannelHandler initializePipeline(
SocketChannel channel,
RpcHandler channelRpcHandler) {
try {
TransportChannelHandler channelHandler = createChannelHandler(channel, channelRpcHandler);
/**
* 管道设置
* Request时按照顺序执行,TransportFrameDecoder-》MessageDecoder-》IdleStateHandler-》TransportChannelHandler
* Response时按照逆序执行,IdleStateHandler-》MessageEncoder
* */
channel.pipeline()
.addLast("encoder", encoder) //为pipeline设置encoder
.addLast(TransportFrameDecoder.HANDLER_NAME, NettyUtils.createFrameDecoder()) //为pipeline设置frameDecoder
.addLast("decoder", decoder) //为pipeline设置decoder
.addLast("idleStateHandler", //为pipeline设置IdleStateHandler,Netty内置对象
new IdleStateHandler(0, 0, conf.connectionTimeoutMs() / 1000))
// NOTE: Chunks are currently guaranteed to be returned in the order of request, but this
// would require more logic to guarantee if this were not part of the same event loop.
.addLast("handler", channelHandler);
return channelHandler;
} catch (RuntimeException e) {
logger.error("Error while initializing Netty pipeline", e);
throw e;
}
}
首先是调用createChannelHandler方法创建TransportChannelHandler对象,createChannelHandler代码如下:
/**
* TransportChannelHandler
* 在服务端代理TransportRequestHandler处理请求消息
* 在客户端代理TransportResponseHandler处理相应信息
*
* */
private TransportChannelHandler createChannelHandler(Channel channel, RpcHandler rpcHandler) {
// 创建TransportChannelHandler的同时,创建了TransportResponseHandler、TransportRequestHandler和TransportClient
TransportResponseHandler responseHandler = new TransportResponseHandler(channel);
// 真正意义上的创建TransportClient
TransportClient client = new TransportClient(channel, responseHandler);
TransportRequestHandler requestHandler = new TransportRequestHandler(channel, client,
rpcHandler);
return new TransportChannelHandler(client, responseHandler, requestHandler,
conf.connectionTimeoutMs(), closeIdleConnections);
}
创建TransportChannelHandler之前,先创建了TransportResponseHandler、TransportClient和TransportRequestHandler,在这里才是真正意义的创建TransportClient对象,与管道一一对应,保证所有用户使用channel时得到的是同一个TrasportClient对象。TransportChannelHandler在服务端代理TransportRequestHandler处理请求消息,在客户端代理TransportResponseHandler处理相应信息。创建了TransportChannelHandler之后,对管道pipeline进行设置,代码如下:

TransportFrameDecoder、MessageDecoder、TransportChannelHandler本质上都是继承了ChannelInboundHandler,MessageEncoder本质上都是继承了ChannelOutboundHandler,IdleStateHandler本质上都是继承了ChannelInboundHandler,ChannelOutboundHandler(继承和接口实现),根据Netty中handler的执行顺序,得出如下:
Request时按照