由前面的服务暴露可知,Protocl.export->createServer ..->NettyServer.doOpen
所以,从NettyServer开始,这里才是真正用Netty暴露服务的地方
protected void doOpen() throws Throwable {
NettyHelper.setNettyLoggerFactory();
ExecutorService boss = Executors.newCachedThreadPool(new NamedThreadFactory("NettyServerBoss", true));
ExecutorService worker = Executors.newCachedThreadPool(new NamedThreadFactory("NettyServerWorker", true));
ChannelFactory channelFactory = new NioServerSocketChannelFactory(boss, worker, getUrl().getPositiveParameter(Constants.IO_THREADS_KEY, Constants.DEFAULT_IO_THREADS));
bootstrap = new ServerBootstrap(channelFactory);
final NettyHandler nettyHandler = new NettyHandler(getUrl(), this);
channels = nettyHandler.getChannels();
bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
public ChannelPipeline getPipeline() {
NettyCodecAdapter adapter = new NettyCodecAdapter(getCodec() ,getUrl(), NettyServer.this);
ChannelPipeline pipeline = Channels.pipeline();
/*int idleTimeout = getIdleTimeout();
if (idleTimeout > 10000) {
pipeline.addLast("timer", new IdleStateHandler(timer, idleTimeout / 1000, 0, 0));
}*/
pipeline.addLast("decoder", adapter.getDecoder());
pipeline.addLast("encoder", adapter.getEncoder());
pipeline.addLast("handler", nettyHandler);
return pipeline;
}
});
// bind
channel = bootstrap.bind(getBindAddress());
}
Netty:
boss pool:处理Acceptor事件,负责连接的建立,连接建立后将交由worker pool处理,默认一个线程
worker pool:处理I/O读写事件,线程池默认大小 netty worker=处理器个数 + 1,
public static final int DEFAULT_IO_THREADS = Runtime.getRuntime().availableProcessors() + 1;
dubbo 业务线程池:默认线程数=200,public static final int DEFAULT_THREADS = 200;
Channel
ChannelPipline:
包含一系列handler,addLast,利用事件传输机制,handler按顺序触发
图片:https://segmentfault.com/img/bVEPxU?w=1225&h=397
ChannelHandler:
pipeline.addLast("decoder", adapter.getDecoder());
pipeline.addLast("handler", nettyHandler);
NettyCodecAdapter 编解码
NettyHandler:
NettyHandler extends SimpleChannelHandler
继承netty SimpleChannelHandler,需实现相关方法,如
channelConnected
messageReceived
NettyHandler.messageReceived
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
NettyChannel channel = NettyChannel.getOrAddChannel(ctx.getChannel(), url, handler);
try {
handler.received(channel, e.getMessage());
} finally {
NettyChannel.removeChannelIfDisconnected(ctx.getChannel());
}
}
NettyChannel:dubbo封装的channel,里面映射了真正的Channel
其中,NettyHandler中的handler就是在NettyServer中传入的this
messageReceived -> handler.received -> NettyServer.received -> AbstractPeer.received -> handler.received ->
而AbstractPeer.handler 是在NettyServer的构造方法中传入的:ChannelHandlers.wrap(handler, ExecutorUtil.setThreadName(url, SERVER_THREAD_POOL_NAME))
wrap了好几层,这里最终的handler是:
MultiMessageHandler -> HeartbeatHandler -> AllChannelHandler
->AllChannelHandler.received
这里很重要,从这里开始,开启了另外一个线程池,这是dubbo的业务线程池,由netty的worker线程将事件提交给dubbo的线程池,这样就不会造成netty worker线程的阻塞了:
-> ChannelEventRunnable.run
AllChannelHandler.received
public void received(Channel channel, Object message) throws RemotingException {
ExecutorService cexecutor = getExecutorService();
try {
cexecutor.execute(new ChannelEventRunnable(channel, handler, ChannelState.RECEIVED, message));
} catch (Throwable t) {
throw new ExecutionException(message, channel, getClass() + " error when process received event .", t);
}
}
参考:
https://segmentfault.com/a/1190000007282789
https://segmentfault.com/a/1190000007308934