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的層級換下以下: 輸入圖片說明圖片

相關文章
相關標籤/搜索