dubbo默认的是以netty为通讯框架,有了解过netty的清楚,不管是客户端还是服务端,在通讯过程中所产生的事件:连接断开,读/写,接受等事件,必定在:ChannelPipeline里面处理,而在:ChannelPipeline具体处理的就是:ChannelHandler了,据此,我们从学习笔记—DUBBO的服务暴露以及源码分析分析过,服务在暴露过程中,会建立NettyServer并且打开通道:
@Override
protected void doOpen() throws Throwable {
bootstrap = new ServerBootstrap();
bossGroup = new NioEventLoopGroup(1, new DefaultThreadFactory("NettyServerBoss", true));
workerGroup = new NioEventLoopGroup(getUrl().getPositiveParameter(Constants.IO_THREADS_KEY, Constants.DEFAULT_IO_THREADS),
new DefaultThreadFactory("NettyServerWorker", true));
final NettyServerHandler nettyServerHandler = new NettyServerHandler(getUrl(), this);
channels = nettyServerHandler.getChannels();
bootstrap.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childOption(ChannelOption.TCP_NODELAY, Boolean.TRUE)
.childOption(ChannelOption.SO_REUSEADDR, Boolean.TRUE)
.childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)
.childHandler(new ChannelInitializer<NioSocketChannel>() {
@Override
protected void initChannel(NioSocketChannel ch) throws Exception {
NettyCodecAdapter adapter = new NettyCodecAdapter(getCodec(), getUrl(), NettyServer.this);
ch.pipeline()//.addLast("logging",new LoggingHandler(LogLevel.INFO))//for debug
.addLast("decoder", adapter.getDecoder())
.addLast("encoder", adapter.getEncoder())
.addLast("handler", nettyServerHandler);
}
});
// bind
ChannelFuture channelFuture = bootstrap.bind(getBindAddress());
channelFuture.syncUninterruptibly();
channel = channelFuture.channel();
}
由代码以及使用netty的api的分析,可以大胆的猜想:就是在:NettyServerHandler 处理:
断点可以确定这个猜想是对的,接着调用链:
NettyServer-》AbstractServer-》MultiMessageHandler-》HeartbeatHandler-》AllChannelHandler,断点:
可以看出来,这里开始利用线程池来创建新的现场来处理,这里实现了IO线程与业务线程的处理,将收到请求信息,信息类型,对应处理的nettyChannel(以便处理完成发送结果)等信息交给业务线程池来处理;
到:ChannelEventRunnable这个类了:
@Override
public void run() {
if (state == ChannelState.RECEIVED) {
try {
System.out.println(" ChannelEventRunnable.received(channel, message);"+handler.getClass().getName()+" "+message);
handler.received(channel, message);
} catch (Exception e) {
logger.warn("ChannelEventRunnable handle " + state + " operation error, channel is " + channel
+ ", message is " + message, e);
}
} else {
switch (state) {
case CONNECTED:
try {
handler.connected(channel);
} catch (Exception e) {
logger.warn("ChannelEventRunnable handle " + state + " operation error, channel is " + channel, e);
}
break;
case DISCONNECTED:
try {
handler.disconnected(channel);
} catch (Exception e) {
logger.warn("ChannelEventRunnable handle " + state + " operation error, channel is " + channel, e);
}
break;
case SENT:
try {
handler.sent(channel, message);
} catch (Exception e) {
logger.warn("ChannelEventRunnable handle " + state + " operation error, channel is " + channel
+ ", message is " + message, e);
}
case CAUGHT:
try {
handler.caught(channel, exception);
} catch (Exception e) {
logger.warn("ChannelEventRunnable handle " + state + " operation error, channel is " + channel
+ ", message is: " + message + ", exception is " + exception, e);
}
break;
default:
logger.warn("unknown state: " + state + ", message is " + message);
}
}
}
可以看到这里处理不同的事件,我们关注读取事件,开始了 D
ecodeHandler-》HeaderExchangeHandler,断点:
接着调用了:DubboProtocol的方法来获取对应本地暴露的存根:Exporter:
这里获取:Exporter后便可以获取对应Invoker对象,接着就是责任链:filter了,
再通过责任链返回,调用: channel.send(response) 方法返回给消费端;