Dubbo 源碼分析 —— 核心流程一覽


我準(zhǔn)備戰(zhàn)斗到最后,不是因?yàn)槲矣赂液汪ぃ俏蚁胍娮C一切。 ——雙雪濤《獵人》

[TOC]
Thinking

  1. 一個技術(shù)碟刺,為什么要用它锁保,解決了那些問題?
  2. 如果不用會怎么樣半沽,有沒有其它的解決方法爽柒?
  3. 對比其它的解決方案,為什么最終選擇了這種者填,都有何利弊浩村?
  4. 你覺得項(xiàng)目中還有那些地方可以用到,如果用了會帶來那些問題占哟?
  5. 這些問題你又如何去解決的呢心墅?

本文基于Dubbo 2.6.7-SNAPSHOT

? 本文主要基于《Dubbo 開發(fā)指南 —— 框架設(shè)計(jì)》

1、整體設(shè)計(jì)

dubbo-framework.jpg

圖例說明:

  • 圖中左邊淡藍(lán)背景的為服務(wù)消費(fèi)方使用的接口榨乎,右邊淡綠色背景的為服務(wù)提供方使用的接口怎燥,位于中軸線上的為雙方都用到的接口。
  • 圖中從下至上分為十層蜜暑,各層均為單向依賴铐姚,右邊的黑色箭頭代表層之間的依賴關(guān)系,每一層都可以剝離上層被復(fù)用肛捍,其中隐绵,Service 和 Config 層為 API,其它各層均為 SPI拙毫。
  • 圖中綠色小塊的為擴(kuò)展接口氢橙,藍(lán)色小塊為實(shí)現(xiàn)類,圖中只顯示用于關(guān)聯(lián)各層的實(shí)現(xiàn)類恬偷。
  • 圖中藍(lán)色虛線為初始化過程,即啟動時組裝鏈,紅色實(shí)線為方法調(diào)用過程袍患,即運(yùn)行時調(diào)時鏈坦康,紫色三角箭頭為繼承,可以把子類看作父類的同一個節(jié)點(diǎn)诡延,線上的文字為調(diào)用的方法滞欠。

1.1 各層說明

  • ========================== Business==============================
  • Service業(yè)務(wù)層:業(yè)務(wù)代碼的接口與實(shí)現(xiàn)。暴露在外實(shí)際的使用Dubbo層肆良。
  • ========================== RPC==============================
  • config 配置層:對外配置接口筛璧,以 ServiceConfig, ReferenceConfig 為中心,可以直接初始化配置類惹恃,也可以通過 spring 解析配置生成配置類
    • dubbo-config 模塊實(shí)現(xiàn)
  • proxy 服務(wù)代理層:服務(wù)接口透明代理夭谤,生成服務(wù)的客戶端 Stub 和服務(wù)器端 Skeleton, 以 ServiceProxy 為中心,擴(kuò)展接口為 ProxyFactory
    • dubbo-rpc 模塊實(shí)現(xiàn)
  • registry 注冊中心層:封裝服務(wù)地址的注冊與發(fā)現(xiàn)巫糙,以服務(wù) URL 為中心朗儒,擴(kuò)展接口為 RegistryFactory, Registry, RegistryService
    • dubbo-registry 模塊實(shí)現(xiàn)
  • cluster 路由層:封裝多個提供者的路由及負(fù)載均衡,并橋接注冊中心参淹,以 Invoker 為中心醉锄,擴(kuò)展接口為 Cluster, Directory, Router, LoadBalance
    • dubbo-cluster 模塊實(shí)現(xiàn)
  • monitor 監(jiān)控層:RPC 調(diào)用次數(shù)和調(diào)用時間監(jiān)控,以 Statistics 為中心浙值,擴(kuò)展接口為 MonitorFactory, Monitor, MonitorService
    • dubbo-monitor 模塊實(shí)現(xiàn)
  • protocol 遠(yuǎn)程調(diào)用層:封裝 RPC 調(diào)用恳不,以 Invocation, Result 為中心,擴(kuò)展接口為 Protocol, Invoker, Exporter
    • dubbo-rpc 模塊實(shí)現(xiàn)
  • ========================== Remoting============================
  • exchange 信息交換層:封裝請求響應(yīng)模式开呐,同步轉(zhuǎn)異步烟勋,以 Request, Response 為中心,擴(kuò)展接口為 Exchanger, ExchangeChannel, ExchangeClient, ExchangeServer
    • dubbo-remoting-api 模塊定義接口
  • transport 網(wǎng)絡(luò)傳輸層:抽象 mina 和 netty 為統(tǒng)一接口负蚊,以 Message 為中心神妹,擴(kuò)展接口為 Channel, Transporter, Client, Server, Codec
    • dubbo-remoting-api 模塊定義接口
  • serialize 數(shù)據(jù)序列化層:可復(fù)用的一些工具,擴(kuò)展接口為 Serialization, ObjectInput, ObjectOutput, ThreadPool
    • dubbo-common 模塊實(shí)現(xiàn)家妆。

1.2 關(guān)系說明

在 RPC 中鸵荠,Protocol 是核心層,也就是只要有 Protocol + Invoker + Exporter 就可以完成非透明的 RPC 調(diào)用伤极,然后在 Invoker 的主過程上 Filter 攔截點(diǎn)蛹找。

  • dubbo-rpc 模塊可以獨(dú)立完成該功能

圖中的 Consumer 和 Provider 是抽象概念,只是想讓看圖者更直觀的了解哪些類分屬于客戶端與服務(wù)器端哨坪,不用 Client 和 Server 的原因是 Dubbo 在很多場景下都使用 Provider, Consumer, Registry, Monitor 劃分邏輯拓普節(jié)點(diǎn)庸疾,保持統(tǒng)一概念。

而 Cluster 是外圍概念当编,所以 Cluster 的目的是將多個 Invoker 偽裝成一個 Invoker届慈,這樣其它人只要關(guān)注 Protocol 層 Invoker 即可,加上 Cluster 或者去掉 Cluster 對其它層都不會造成影響,因?yàn)橹挥幸粋€提供者時金顿,是不需要 Cluster 的

  • dubbo-cluster 模塊提供的是非必需的功能臊泌,移除不會影響到其它模塊。RPC模塊也可以正常運(yùn)行揍拆。

Proxy 層封裝了所有接口的透明化代理渠概,而在其它層都以 Invoker 為中心,只有到了暴露給用戶使用時嫂拴,才用 Proxy 將 Invoker 轉(zhuǎn)成接口播揪,或?qū)⒔涌趯?shí)現(xiàn)轉(zhuǎn)成 Invoker,也就是去掉 Proxy 層 RPC 是可以 Run 的筒狠,只是不那么透明猪狈,不那么看起來像調(diào)本地服務(wù)一樣調(diào)遠(yuǎn)程服務(wù)。

  • 簡單粗暴的說窟蓝,Proxy 會攔截 service.doSomething(args) 的調(diào)用罪裹,“轉(zhuǎn)發(fā)”給該 Service 對應(yīng)的 Invoker ,從而實(shí)現(xiàn)透明化的代理运挫。

而 Remoting 實(shí)現(xiàn)是 Dubbo 協(xié)議的實(shí)現(xiàn)状共,如果你選擇 RMI 協(xié)議,整個 Remoting 都不會用上谁帕,Remoting 內(nèi)部再劃為 Transport 傳輸層和 Exchange 信息交換層峡继,Transport 層只負(fù)責(zé)單向消息傳輸,是對 Mina, Netty, Grizzly 的抽象匈挖,它也可以擴(kuò)展 UDP 傳輸碾牌,而 Exchange 層是在傳輸層之上封裝了 Request-Response 語義。

Registry 和 Monitor 實(shí)際上不算一層儡循,而是一個獨(dú)立的節(jié)點(diǎn)舶吗,只是為了全局概覽,用層的方式畫在一起

2择膝、核心流程

2.1 調(diào)用鏈

dubbo-extension.jpg
  • 垂直分層如下:
    • 下方 淡藍(lán)背景( Consumer ):服務(wù)消費(fèi)方使用的接口
    • 上方 淡綠色背景( Provider ):服務(wù)提供方使用的接口
    • 中間 粉色背景( Remoting ):通信部分的接口
  • 自 LoadBalance 向上誓琼,每一行分成了多個相同的 Interface ,指的是負(fù)載均衡后肴捉,向 Provider 發(fā)起調(diào)用腹侣。
  • 左邊 括號 部分,代表了垂直部分更細(xì)化的分層齿穗,依次是:Common傲隶、Remoting、RPC窃页、Interface 跺株。
  • 右邊 藍(lán)色虛線( Init ) 為初始化過程复濒,通過對應(yīng)的組件進(jìn)行初始化。例如帖鸦,ProxyFactory 初始化出 Proxy 芝薇。

2.2 暴露服務(wù)

服務(wù)提供方暴露服務(wù)藍(lán)色初始化鏈(Init)時序圖:


dubbo-export.jpg

2.3.4 步 為本文重點(diǎn):getInvoker()

2.3 引用服務(wù)

消費(fèi)方引用服務(wù)的藍(lán)色初始化鏈


dubbo_rpc_refer.jpg

第5步:refer() 第12步 都為本文重點(diǎn)。

3作儿、領(lǐng)域模型

本章分享的位于Dubbo-rpc-api目錄中,如下圖紅框部分:

領(lǐng)域模型

在 Dubbo 的核心領(lǐng)域模型中:

  • Protocol 是服務(wù)域馋劈,它是 Invoker 暴露和引用的主功能入口攻锰,它負(fù)責(zé) Invoker 的生命周期管理。
  • Invoker 是實(shí)體域妓雾,它是 Dubbo 的核心模型娶吞,其它模型都向它靠擾,或轉(zhuǎn)換成它械姻,它代表一個可執(zhí)行體妒蛇,可向它發(fā)起 invoke 調(diào)用,它有可能是一個本地的實(shí)現(xiàn)楷拳,也可能是一個遠(yuǎn)程的實(shí)現(xiàn)绣夺,也可能一個集群實(shí)現(xiàn)。
  • Invocation 是會話域欢揖,它持有調(diào)用過程中的變量陶耍,比如方法名,參數(shù)等她混。

3.1 Invoker

com.alibaba.dubbo.rpc

Invoker 是實(shí)體域烈钞,它是 Dubbo 的核心模型,其它模型都向它靠擾坤按,或轉(zhuǎn)換成它毯欣。

它代表一個可執(zhí)行體,可向它發(fā)起 invoke 調(diào)用臭脓,它有可能是一個本地的實(shí)現(xiàn)酗钞,也可能是一個遠(yuǎn)程的實(shí)現(xiàn),也可能一個集群實(shí)現(xiàn)谢鹊。

public interface Invoker<T> extends Node {

    /**
     * get service interface.
     *
     * #getInterface() 獲取Service接口
     *
     * @return service interface.
     */
    Class<T> getInterface();

    /**
     * invoke.
     * 調(diào)用方法
     *
     * @param invocation
     * @return result
     * @throws RpcException
     */
    Result invoke(Invocation invocation) throws RpcException;

}

3.1.1 詳解Invoker

在dubbo中算吩,萬物皆是Invoker,即便是Exporter也是由Invoker進(jìn)化而成的

? 由于Invoker在Dubbo領(lǐng)域模型中非常重要的一個概念佃扼,很多設(shè)計(jì)思路都是向它靠攏偎巢。

這一思想滲透在整個實(shí)現(xiàn)代碼里。

下面簡單的說明Invoker的兩種實(shí)現(xiàn):服務(wù)提供的invoker和服務(wù)消費(fèi)的invoker

滿眼都是Invoker

結(jié)合Dubbo demo中的 消費(fèi)和提供者代碼來理解上圖兼耀。

  • 服務(wù)消費(fèi)者代碼:
public class DemoClientAction {
    private DemoServer demoServer;

    public void setDemoServer(DemoServer demoServer) {
        this.demoServer = demoServer;
    }

    public void start() {
        String hello = demoServer.sayHello("world");
    }
}
  • 上面代碼中的 DemoService 就是上圖中服務(wù)消費(fèi)端的 Proxy压昼,用戶代碼通過這個 Proxy 調(diào)用其對應(yīng)的 Invoker求冷,而該 Invoker 實(shí)現(xiàn)了真正的遠(yuǎn)程服務(wù)調(diào)用。
  • 服務(wù)提供者代碼:
public class DemoServiceImpl implements DemoService {

    public String sayHello(String name) throws RemoteException {
        return "Hello " + name;
    }
}
  • 上面這個類會被封裝成為一個 AbstractProxyInvoker 實(shí)例窍霞,并新生成一個 Exporter 實(shí)例匠题。這樣當(dāng)網(wǎng)絡(luò)通訊層收到一個請求后,會找到對應(yīng)的 Exporter 實(shí)例但金,并調(diào)用它所對應(yīng)的 AbstractProxyInvoker 實(shí)例韭山,從而真正調(diào)用了服務(wù)提供者的代碼。

3.1.2Invoker 類圖

? 上文所提到的冷溃,在Dubbo中invoker是一個非常重要的概念钱磅,既可以理解為萬物皆為Invoker。所以在Dubbo中的實(shí)現(xiàn)類非常多似枕。

Invoker類圖

3.2 Invocation

com.alibaba.dubbo.rpc.Invocation

Invocation 是會話域盖淡,它持有調(diào)用過程中的變量,比如方法名凿歼,參數(shù)等褪迟。

public interface Invocation {

    /**
     * get method name.
     *
     * 獲取方法名
     * @return method name.
     * @serial
     */
    String getMethodName();

    /**
     * get parameter types.
     *
     * 獲取方法參數(shù)類型數(shù)組
     * @return parameter types.
     * @serial
     */
    Class<?>[] getParameterTypes();

    /**
     * get arguments.
     *
     * 獲取方法參數(shù)數(shù)組
     * @return arguments.
     * @serial
     */
    Object[] getArguments();

    /**
     * get attachments.
     *
     * 獲取隱式參數(shù)相關(guān)
     * @return attachments.
     * @serial
     */
    Map<String, String> getAttachments();

    /**
     * get attachment by key.
     *
     * @return attachment value.
     * @serial
     */
    String getAttachment(String key);

    /**
     * get attachment by key with default value.
     *
     * @return attachment value.
     * @serial
     */
    String getAttachment(String key, String defaultValue);

    /**
     * get the invoker in current context.
     *
     * 在當(dāng)前上下文中獲取調(diào)用者 invoker
     *
     * 獲取對應(yīng)的invoker對象
     *
     * @return invoker.
     * @transient
     */
    Invoker<?> getInvoker();

}

3.2.1 類圖

Invocation類圖
  • DecodeableRpcInvocation:是Dubbo協(xié)議獨(dú)有的。

3.3 Result

com.alibaba.dubbo.rpc.Result

Result 是會話域答憔,它持有調(diào)用過程中返回值味赃,異常等。

? RPC調(diào)用的結(jié)果集

public interface Result {

    /**
     * Get invoke result.
     * <p>
     * 獲取返回值
     *
     * @return result. if no result return null.
     */
    Object getValue();

    /**
     * Get exception.
     * <p>
     * 獲取返回的異常
     *
     * @return exception. if no exception return null.
     */
    Throwable getException();

    /**
     * Has exception.
     * <p>
     * 判斷是否存在異常
     *
     * @return has exception.
     */
    boolean hasException();

    /**
     * Recreate.
     * <p>
     * <code>
     * if (hasException()) {
     * throw getException();
     * } else {
     * return getValue();
     * }
     * </code>
     * <p>
     * com.alibaba.dubbo.rpc.RpcResult
     * RpcResult 中針對recreate() 的實(shí)現(xiàn)攀唯。
     *
     * @return result.
     * @throws if has exception throw it.
     * @see RpcResult // 具體實(shí)現(xiàn)
     */
    Object recreate() throws Throwable;

    /**
     * @see com.alibaba.dubbo.rpc.Result#getValue()
     * @deprecated Replace to getValue()
     */
    @Deprecated
    Object getResult();

    /**
     * 下面的getAttachments等方法 都是獲取但會的隱式參數(shù)相關(guān)洁桌。
     */

    /**
     * get attachments.
     *
     * @return attachments.
     */
    Map<String, String> getAttachments();

    /**
     * get attachment by key.
     *
     * @return attachment value.
     */
    String getAttachment(String key);

    /**
     * get attachment by key with default value.
     *
     * @return attachment value.
     */
    String getAttachment(String key, String defaultValue);

}

#recreate()的具體實(shí)現(xiàn):

    private Object result;

    private Throwable exception;  

@Override
public Object recreate() throws Throwable {
        if (exception != null) {
            throw exception;
        }
        return result;
    }

3.3.1 類圖

Result類圖

3.4 Filter

com.alibaba.dubbo.rpc.Filter

過濾器接口,和我們平時理解的 javax.servlet.Filter 基本一致侯嘀。

/**
 * Filter. (SPI, Singleton, ThreadSafe)
 */
@SPI
public interface Filter {

    /**
     * do invoke filter.
     執(zhí)行invoker的過濾邏輯另凌。
     * <p>
     * <code>
     * // before filter 自己實(shí)現(xiàn)
     * Result result = invoker.invoke(invocation);
     * // after filter 自己實(shí)現(xiàn)
     * return result;
     * </code>
     *
     * @param invoker    service
     * @param invocation invocation.
     * @return invoke result.
     * @throws RpcException
     * @see com.alibaba.dubbo.rpc.Invoker#invoke(Invocation)
     */
    Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException;

}

3.4.1 類圖

Filter類圖

4.5 ProxyFactory

com.alibaba.dubbo.rpc.ProxyFactory代理工廠類

/**
 * ProxyFactory. (API/SPI, Singleton, ThreadSafe)
 */
@SPI("javassist")
public interface ProxyFactory {

    /**
     * create proxy.
     *
     * 創(chuàng)建Proxy,在引用服務(wù)調(diào)用戒幔。
     *
     * @param invoker
     * @return proxy
     */
    @Adaptive({Constants.PROXY_KEY})
    <T> T getProxy(Invoker<T> invoker) throws RpcException;

    /**
     * create proxy.
     *
     * @param invoker
     * @return proxy
     */
    @Adaptive({Constants.PROXY_KEY})
    <T> T getProxy(Invoker<T> invoker, boolean generic) throws RpcException;

    /**
     * create invoker.
     *
     * 創(chuàng)建Invoker吠谢,在暴露服務(wù)時調(diào)用。
     *
     * @param <T>
     * @param proxy Service對象
     * @param type  Service接口類型
     * @param url   Service對應(yīng)的Dubbo URL
     * @return invoker
     */
    @Adaptive({Constants.PROXY_KEY})
    <T> Invoker<T> getInvoker(T proxy, Class<T> type, URL url) throws RpcException;
}

服務(wù)消費(fèi)者消費(fèi)一個服務(wù)的詳細(xì)過程

dubbo_rpc_refer.jpg

首先 ReferenceConfig 類的 init 方法調(diào)用 Protocolrefer 方法生成 Invoker 實(shí)例(如上圖中的紅色部分)诗茎,這是服務(wù)消費(fèi)的關(guān)鍵工坊。接下來把 Invoker 轉(zhuǎn)換為客戶端需要的接口(如:HelloWorld)。

  • 從圖中我們可以看出敢订,方法的 invoker 參數(shù)王污,通過 Protocol 將 Service接口 創(chuàng)建出 Invoker 。
  • 通過創(chuàng)建 Service 的 Proxy 楚午,實(shí)現(xiàn)我們在業(yè)務(wù)代理調(diào)用 Service 的方法時昭齐,透明的內(nèi)部轉(zhuǎn)換成調(diào)用 Invoker 的 #invoke(Invocation) 方法
  • 服務(wù)提供者暴露服務(wù)的 主過程 如下圖:

首先 ServiceConfig 類拿到對外提供服務(wù)的實(shí)際類 ref(如:HelloWorldImpl),然后通過 ProxyFactory 類的 getInvoker 方法使用 ref 生成一個 AbstractProxyInvoker 實(shí)例,到這一步就完成具體服務(wù)到 Invoker 的轉(zhuǎn)化矾柜。接下來就是 Invoker 轉(zhuǎn)換到 Exporter 的過程阱驾。

從圖中我們可以看出就谜,該方法創(chuàng)建的 Invoker ,下一步會提交給 Protocol 里覆,從 Invoker 轉(zhuǎn)換到 Exporter 丧荐。

Dubbo 的實(shí)現(xiàn)

Dubbo 協(xié)議的 Invoker 轉(zhuǎn)為 Exporter 發(fā)生在 DubboProtocol 類的 export 方法,它主要是打開 socket 偵聽服務(wù)喧枷,并接收客戶端發(fā)來的各種請求虹统,通訊細(xì)節(jié)由 Dubbo 自己實(shí)現(xiàn)。

RMI 的實(shí)現(xiàn)

RMI 協(xié)議的 Invoker 轉(zhuǎn)為 Exporter 發(fā)生在 RmiProtocol類的 export 方法割去,它通過 Spring 或 Dubbo 或 JDK 來實(shí)現(xiàn) RMI 服務(wù)窟却,通訊細(xì)節(jié)這一塊由 JDK 底層來實(shí)現(xiàn),這就省了不少工作量呻逆。

3.5.1 類圖

image-20200205163900241.png

從類圖可以看出,Dubbo支持JavassistJDK Proxy兩種方式生成代理菩帝。

3.6 Protocol

com.alibaba.dubbo.rpc.Protocol Dubbo支持協(xié)議的頂層接口

Protocol 是服務(wù)域咖城,它是 Invoker 暴露和引用的主功能入口。
它負(fù)責(zé) Invoker 的生命周期管理呼奢。

/**
 * Protocol. (API/SPI, Singleton, ThreadSafe)
 *
 * Dubbo 支持RPC協(xié)議的 頂層接口
 */
@SPI("dubbo")
public interface Protocol {

    /**
     * Get default port when user doesn't config the port.
     *
     * 定義 默認(rèn)端口
     *
     * @return default port
     */
    int getDefaultPort();

    /**
     * Export service for remote invocation: <br>
     * 1. Protocol should record request source address after receive a request:
     * RpcContext.getContext().setRemoteAddress();<br>
     * 2. export() must be idempotent, that is, there's no difference between invoking once and invoking twice when
     * export the same URL<br>
     * 3. Invoker instance is passed in by the framework, protocol needs not to care <br>
     *
     * 暴露遠(yuǎn)程調(diào)用服務(wù):
     * 1. 協(xié)議在接受請求時宜雀,應(yīng)該記錄請求的來源地址:RpcContext.getContext().setRemoteAddress();<br>
     * 2. export()必須是冪等的,也就是說握础,在暴露服務(wù)時辐董,一次調(diào)用和兩次調(diào)用時沒有區(qū)別的,
     * 3.傳入的Invoker實(shí)例由框架實(shí)現(xiàn)并傳入禀综,協(xié)議無需關(guān)心简烘。
     *
     * @param <T>     Service type 服務(wù)的類型
     * @param invoker Service invoker 服務(wù)的執(zhí)行體
     * @return exporter reference for exported service, useful for unexport the service later
     * @throws RpcException thrown when error occurs during export the service, for example: port is occupied
     */
    @Adaptive
    <T> Exporter<T> export(Invoker<T> invoker) throws RpcException;

    /**
     * Refer a remote service: <br> 引用遠(yuǎn)程服務(wù)
     * 1. When user calls `invoke()` method of `Invoker` object which's returned from `refer()` call, the protocol
     * needs to correspondingly execute `invoke()` method of `Invoker` object <br>
     * 2. It's protocol's responsibility to implement `Invoker` which's returned from `refer()`. Generally speaking,
     * protocol sends remote request in the `Invoker` implementation. <br>
     * 3. When there's check=false set in URL, the implementation must not throw exception but try to recover when
     * connection fails.
     *
     * 引用遠(yuǎn)程服務(wù):
     * 1. 當(dāng)用戶調(diào)用Refer()所返回的Invoker對象的invoke()方法時,協(xié)議需要相應(yīng)地執(zhí)行Invoker對象的Invoke()方法
     * 2. 實(shí)現(xiàn)由`refer()`返回的`Invoker`是協(xié)議的責(zé)任定枷。一般來說孤澎,協(xié)議在`Invoker`實(shí)現(xiàn)中發(fā)送遠(yuǎn)程請求。
     * 3. 當(dāng)url中設(shè)置了 check = false時欠窒,連接失敗時不能拋出異常覆旭,且只能內(nèi)部消化。
     *
     * @param <T>  Service type 服務(wù)的類型
     * @param type Service class 服務(wù)的 class對象
     * @param url  URL address for the remote service 遠(yuǎn)程服務(wù)的url地址
     * @return invoker service's local proxy 服務(wù)的本地代理
     * @throws RpcException when there's any error while connecting to the service provider 當(dāng)連接服務(wù)提供方失敗時岖妄,拋出該異常型将。
     */
    @Adaptive
    <T> Invoker<T> refer(Class<T> type, URL url) throws RpcException;

    /**
     * Destroy protocol: <br>
     * 1. Cancel all services this protocol exports and refers <br>
     * 2. Release all occupied resources, for example: connection, port, etc. <br>
     * 3. Protocol can continue to export and refer new service even after it's destroyed.
     *
     * 銷毀/釋放協(xié)議:
     * 1. 取消該協(xié)議所有已經(jīng)暴露和引用的服務(wù)。<br>
     * 2. 釋放協(xié)議所占用的所有資源荐虐,比如:連接七兜,端口等等。缚俏。
     * 3. 協(xié)議即使銷毀后也可以繼續(xù)暴露并引用新服務(wù)惊搏。
     */
    void destroy();

}

3.6.1 類圖

Protocl類圖

從類圖就可以很清楚的看出贮乳,Dubbo支持多協(xié)議。

3.7 Exporter

com.alibaba.dubbo.rpc.Exporter

Exporter恬惯,Invoker 暴露服務(wù)在Protocol上的對象向拆。

/**
 * Exporter. (API/SPI, Prototype, ThreadSafe)
 *
 * 暴露服務(wù)的 頂層接口
 *
 * @see com.alibaba.dubbo.rpc.Protocol#export(Invoker)
 * @see com.alibaba.dubbo.rpc.ExporterListener
 * @see com.alibaba.dubbo.rpc.protocol.AbstractExporter
 */
public interface Exporter<T> {

    /**
     * get invoker.
     *
     * 獲取對應(yīng)的Invoker
     *
     * @return invoker
     */
    Invoker<T> getInvoker();

    /**
     * unexport.
     *
     * 取消 暴露
     * <p>
     * <code>
     * getInvoker().destroy();
     * </code>
     */
    void unexport();

}

3.7.1 類圖


類圖

3.8 ExporterListener

com.alibaba.dubbo.rpc.ExporterListener

Exporter 監(jiān)聽器

/**
 * ExporterListener. (SPI, Singleton, ThreadSafe)
 */
@SPI
public interface ExporterListener {

    /**
     * The exporter exported.
     *
     * 當(dāng)服務(wù)暴露完成
     *
     * @param exporter
     * @throws RpcException
     * @see com.alibaba.dubbo.rpc.Protocol#export(Invoker)
     */
    void exported(Exporter<?> exporter) throws RpcException;

    /**
     * The exporter unexported.
     *
     * 當(dāng)服務(wù)取消暴露完成
     *
     * @param exporter
     * @throws RpcException
     * @see com.alibaba.dubbo.rpc.Exporter#unexport()
     */
    void unexported(Exporter<?> exporter);

}

3.8.1 類圖

3.9 InvokerListener

com.alibaba.dubbo.rpc.InvokerListener invoker監(jiān)聽器

/**
 * InvokerListener. (SPI, Singleton, ThreadSafe)
 * Invoker 監(jiān)聽器
 */
@SPI
public interface InvokerListener {

    /**
     * The invoker referred
     *
     * 當(dāng)服務(wù)引用完成
     *
     * @param invoker
     * @throws RpcException
     * @see com.alibaba.dubbo.rpc.Protocol#refer(Class, com.alibaba.dubbo.common.URL)
     */
    void referred(Invoker<?> invoker) throws RpcException;

    /**
     * The invoker destroyed.
     *
     * 當(dāng)服務(wù)銷毀引用完成
     *
     * @param invoker
     * @see com.alibaba.dubbo.rpc.Invoker#destroy()
     */
    void destroyed(Invoker<?> invoker);

}

3.9.1 類圖

4、總結(jié)

? 本文重點(diǎn)概述了酪耳,Dubbo在服務(wù)的暴露與引用的大概流程浓恳。

本文僅供筆者本人學(xué)習(xí),一起進(jìn)步碗暗!

——努力努力再努力xLg

加油颈将!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市言疗,隨后出現(xiàn)的幾起案子晴圾,更是在濱河造成了極大的恐慌,老刑警劉巖噪奄,帶你破解...
    沈念sama閱讀 221,406評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件死姚,死亡現(xiàn)場離奇詭異,居然都是意外死亡勤篮,警方通過查閱死者的電腦和手機(jī)都毒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,395評論 3 398
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來碰缔,“玉大人账劲,你說我怎么就攤上這事〗鹇眨” “怎么了昭殉?”我有些...
    開封第一講書人閱讀 167,815評論 0 360
  • 文/不壞的土叔 我叫張陵贷盲,是天一觀的道長。 經(jīng)常有香客問我,道長琅豆,這世上最難降的妖魔是什么朱浴? 我笑而不...
    開封第一講書人閱讀 59,537評論 1 296
  • 正文 為了忘掉前任七蜘,我火速辦了婚禮沃粗,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘喘鸟。我一直安慰自己匆绣,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,536評論 6 397
  • 文/花漫 我一把揭開白布什黑。 她就那樣靜靜地躺著崎淳,像睡著了一般。 火紅的嫁衣襯著肌膚如雪愕把。 梳的紋絲不亂的頭發(fā)上拣凹,一...
    開封第一講書人閱讀 52,184評論 1 308
  • 那天森爽,我揣著相機(jī)與錄音,去河邊找鬼嚣镜。 笑死爬迟,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的菊匿。 我是一名探鬼主播付呕,決...
    沈念sama閱讀 40,776評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼跌捆!你這毒婦竟也來了徽职?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,668評論 0 276
  • 序言:老撾萬榮一對情侶失蹤佩厚,失蹤者是張志新(化名)和其女友劉穎姆钉,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體抄瓦,經(jīng)...
    沈念sama閱讀 46,212評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡育韩,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,299評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了闺鲸。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,438評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡埃叭,死狀恐怖摸恍,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情赤屋,我是刑警寧澤立镶,帶...
    沈念sama閱讀 36,128評論 5 349
  • 正文 年R本政府宣布,位于F島的核電站类早,受9級特大地震影響媚媒,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜涩僻,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,807評論 3 333
  • 文/蒙蒙 一缭召、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧逆日,春花似錦嵌巷、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,279評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至坪圾,卻和暖如春晓折,著一層夾襖步出監(jiān)牢的瞬間惑朦,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,395評論 1 272
  • 我被黑心中介騙來泰國打工漓概, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留漾月,地道東北人。 一個月前我還...
    沈念sama閱讀 48,827評論 3 376
  • 正文 我出身青樓垛耳,卻偏偏與公主長得像栅屏,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子堂鲜,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,446評論 2 359

推薦閱讀更多精彩內(nèi)容