Dubbo-Netty

由前面的服务暴露可知,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

你可能感兴趣的:(Dubbo-Netty)