dubbo remoting(3)

上文说了dubbo remoting 的发送、处理逻辑。本文的重点是dubbo remoting的代码逻辑,看看这块是如何组织代码解决问题的。咱们不谈代码的来由,须要读者对dubbo remoting的代码有必定的了解。 输入图片说明java

dubbo remoting的代码要涉及到发送数据的各个方面:通道channel、处理器handler、序列化反序列化、编解码codec。服务器

#通道 dubbo里面的通道具体有三种:Grizzly、Netty、Mina的。 #处理器 有了通道就有了发送接收数据的工具。数据发送接收须要作一系列的逻辑处理。这些逻辑处理就是处理器要作的事情。处理器要作的事情就是将channel包装成channel事务ChannelEventRunnable,而后配置一个线程池处理该信息。工具

executor.execute(new ChannelEventRunnable(channel, handler ,ChannelState.DISCONNECTED));

渠道那么多,他们是如何选择处理器的呢?答案是派发器Dispatcher,派发起决定哪一个渠道使用哪一个处理器。 那派发器有是何时指定的呢? 首先咱们看代码ChannelHandlersurl

*/
public class ChannelHandlers {

    public static ChannelHandler wrap(ChannelHandler handler, URL url){
        return ChannelHandlers.getInstance().wrapInternal(handler, url);
    }

    protected ChannelHandlers() {}

    protected ChannelHandler wrapInternal(ChannelHandler handler, URL url) {
        return new MultiMessageHandler(new HeartbeatHandler(ExtensionLoader.getExtensionLoader(Dispatcher.class)
                                        .getAdaptiveExtension().dispatch(handler, url)));
    }

    private static ChannelHandlers INSTANCE = new ChannelHandlers();

    protected static ChannelHandlers getInstance() {
        return INSTANCE;
    }

    static void setTestingChannelHandlers(ChannelHandlers instance) {
        INSTANCE = instance;
    }
}

该类是一个单利类,在实例化的时候调用了方法wrapInternal,这样返回过去的实例是一个代理类MultiMessageHandler的实例。里面代理了HeartbeatHandler实例,而HeartbeatHandler实例仍是一个代理类,它代理的东西使用spi找到dispacher实现类,经过调用Dispacher的dispatch方法得到了对应的处理器。 接着,咱们发如今实例化客户端的时候调用了AbstractClient的方法spa

protected static ChannelHandler wrapChannelHandler(URL url, ChannelHandler handler){
        url = ExecutorUtil.setThreadName(url, CLIENT_THREAD_POOL_NAME);
        url = url.addParameterIfAbsent(Constants.THREADPOOL_KEY, Constants.DEFAULT_CLIENT_THREADPOOL);
        return ChannelHandlers.wrap(handler, url);
    }

实例化服务器端的时候也使用了如下这段代码线程

public NettyServer(URL url, ChannelHandler handler) throws RemotingException{
        super(url, ChannelHandlers.wrap(handler, ExecutorUtil.setThreadName(url, SERVER_THREAD_POOL_NAME)));
    }

能够看出在客户端、服务器端实例化的时候都调用了ChannelHandlers的wrap方法。至此,通道处理器已经在这个实例化的过程当中准备完毕。 那么问题又来了有三种方式能够发送接收数据(Grizzly、Netty、Mina),选择哪种呢?就是Transporter在起做用。管理器Transporters主要使用spi找到真正额Transporter代理

getTransporter().bind(url, handler);

调用Transporters方法在HeaderExchanger中code

public ExchangeClient connect(URL url, ExchangeHandler handler) throws RemotingException {
        return new HeaderExchangeClient(Transporters.connect(url, new DecodeHandler(new HeaderExchangeHandler(handler))));
    }

在这里又采用了代理模式用DecodeHandler代理了HeaderExchangeHandler,HeaderExchangeHandler实例代理了handler。从后往前看下,就知道了handler的层级换下以下: 输入图片说明图片

相关文章
相关标签/搜索