Dubbo
的整套handler
。。。反正我刚看的时候挺头疼。从Protocol
层到Transporter
层。纵深3层。从DubboProtocol
构建,被逐层传递到NettyServer
,然后在逐层返回。整个过程中,还被不断包裹,从同步到异步,不停变换用法和说法。总之,看得挺累,还是坚持逐个分析一遍。下面来说说。
先看一张图,是使用Dubbo Protocol
并且使用Netty
作为服务器的情况下Handler
的整个包装过程。
解释下上面这张图
1.在DubboProtocol
中构建ExchangeHandler
命名requestHandler
2.在Exchange
层做两次包装new DecodeHandler(new HeaderExchangeHandler(requestHandler))
,具体参考类:HeaderExchanger
① 使用HeaderExchangeHandler
做一次包装,HeaderExchangeHandler
的作用是实现了Reques
t和Response
的概念,当接到received
请求后,将请求转为reply
。请参考类HeaderExchangeHandler
,对这部分不熟悉的可以参考文章dubbo的exchange层
② 使用DecodeHandler
做一次包装,DecodeHandler
的作用是用来对Request Message
和Response Message
做解码操作,解码完成后才能给HeaderExchangeHandler
使用。
3.在Exchange
层包装后的Handler
会被传递到Transporter
层(NettyTransporter
)并且把类型转换成ChannelHandler
,因为ChannelHandler
更为抽象。
4.Handler
在Transporter
层流转,会被传递到NettyServer
中
5.在NettyServer
中被AllChannelHandler
包装,其作用是把NettyServer
接收到的请求转移给Transporter
层的线程池来处理。同步转异步。
6.Handler
被再次NettyServerHandler
包装,NettyServerHandler
的父类是ChannelDuplexHandler
。它属于Netty
的Handler
。由Netty
来管理和调用其中的回调方法。Netty
在接受到channelActive
,channelRead
等方法后,会把请求转移给Dubbo
的Handler
,这样每当请求过来,Netty
的Handler
接到请求就立马把数据和相关信息转交给Dubbo
的Handler
,由Dubbo
的Handler
来管理了。
上述的整个包装过程基本提现了Dubbo Protocol
的Handler
的转移过程。从DubboProtocol
构建逐层向下传递。当Netty
接到TCP
请求后,调用过程又逐层向上传递。下面看下几个关键转折点的代码。
1.请参考DubboProtocol
类,Dubbo Handler
初始化创建的地方。
private ExchangeHandler requestHandler = new ExchangeHandlerAdapter() {
// ----------------------此处省略一堆代码------------------------
};
2.下面看下HeaderExchangeHandler
,Request
和Response
概念重点提现的地方
public class HeaderExchangeHandler implements ChannelHandlerDelegate {
// ----------------------此处生路一堆代码------------------------
@Override // 接受信息
public void received(Channel channel, Object message) throws RemotingException {
channel.setAttribute(KEY_READ_TIMESTAMP, System.currentTimeMillis());
ExchangeChannel exchangeChannel = HeaderExchangeChannel.getOrAddChannel(channel);
try {
if (message instanceof Request) {
// 看看信息是不是Request
// handle request.
Request request = (Request) message;
if (request.isEvent()) {
handlerEvent(channel, request);
} else {