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


我準(zhǔn)備戰(zhàn)斗到最后,不是因?yàn)槲矣赂?,是我想見證一切。 ——雙雪濤《獵人》

[TOC]
Thinking

  1. 一個(gè)技術(shù),為什么要用它,解決了那些問題?
  2. 如果不用會(huì)怎么樣,有沒有其它的解決方法?
  3. 對(duì)比其它的解決方案,為什么最終選擇了這種,都有何利弊?
  4. 你覺得項(xiàng)目中還有那些地方可以用到,如果用了會(huì)帶來那些問題?
  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)色虛線為初始化過程,即啟動(dòng)時(shí)組裝鏈,紅色實(shí)線為方法調(diào)用過程,即運(yùn)行時(shí)調(diào)時(shí)鏈,紫色三角箭頭為繼承,可以把子類看作父類的同一個(gè)節(jié)點(diǎn),線上的文字為調(diào)用的方法。

1.1 各層說明

  • ========================== Business==============================
  • Service業(yè)務(wù)層:業(yè)務(wù)代碼的接口與實(shí)現(xiàn)。暴露在外實(shí)際的使用Dubbo層。
  • ========================== RPC==============================
  • config 配置層:對(duì)外配置接口,以 ServiceConfig, ReferenceConfig 為中心,可以直接初始化配置類,也可以通過 spring 解析配置生成配置類
    • dubbo-config 模塊實(shí)現(xiàn)
  • proxy 服務(wù)代理層:服務(wù)接口透明代理,生成服務(wù)的客戶端 Stub 和服務(wù)器端 Skeleton, 以 ServiceProxy 為中心,擴(kuò)展接口為 ProxyFactory
    • dubbo-rpc 模塊實(shí)現(xiàn)
  • registry 注冊(cè)中心層:封裝服務(wù)地址的注冊(cè)與發(fā)現(xiàn),以服務(wù) URL 為中心,擴(kuò)展接口為 RegistryFactory, Registry, RegistryService
    • dubbo-registry 模塊實(shí)現(xiàn)
  • cluster 路由層:封裝多個(gè)提供者的路由及負(fù)載均衡,并橋接注冊(cè)中心,以 Invoker 為中心,擴(kuò)展接口為 Cluster, Directory, Router, LoadBalance
    • dubbo-cluster 模塊實(shí)現(xiàn)
  • monitor 監(jiān)控層:RPC 調(diào)用次數(shù)和調(diào)用時(shí)間監(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 信息交換層:封裝請(qǐng)求響應(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 的目的是將多個(gè) Invoker 偽裝成一個(gè) Invoker,這樣其它人只要關(guān)注 Protocol 層 Invoker 即可,加上 Cluster 或者去掉 Cluster 對(duì)其它層都不會(huì)造成影響,因?yàn)橹挥幸粋€(gè)提供者時(shí),是不需要 Cluster 的

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

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

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

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

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

2、核心流程

2.1 調(diào)用鏈

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

2.2 暴露服務(wù)

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


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)換成它,它代表一個(gè)可執(zhí)行體,可向它發(fā)起 invoke 調(diào)用,它有可能是一個(gè)本地的實(shí)現(xiàn),也可能是一個(gè)遠(yuǎn)程的實(shí)現(xiàn),也可能一個(gè)集群實(shí)現(xiàn)。
  • Invocation 是會(huì)話域,它持有調(diào)用過程中的變量,比如方法名,參數(shù)等。

3.1 Invoker

com.alibaba.dubbo.rpc

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

它代表一個(gè)可執(zhí)行體,可向它發(fā)起 invoke 調(diào)用,它有可能是一個(gè)本地的實(shí)現(xiàn),也可能是一個(gè)遠(yuǎn)程的實(shí)現(xiàn),也可能一個(gè)集群實(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)域模型中非常重要的一個(gè)概念,很多設(shè)計(jì)思路都是向它靠攏。

這一思想滲透在整個(gè)實(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,用戶代碼通過這個(gè) Proxy 調(diào)用其對(duì)應(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;
    }
}
  • 上面這個(gè)類會(huì)被封裝成為一個(gè) AbstractProxyInvoker 實(shí)例,并新生成一個(gè) Exporter 實(shí)例。這樣當(dāng)網(wǎng)絡(luò)通訊層收到一個(gè)請(qǐng)求后,會(huì)找到對(duì)應(yīng)的 Exporter 實(shí)例,并調(diào)用它所對(duì)應(yīng)的 AbstractProxyInvoker 實(shí)例,從而真正調(diào)用了服務(wù)提供者的代碼。

3.1.2Invoker 類圖

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

Invoker類圖

3.2 Invocation

com.alibaba.dubbo.rpc.Invocation

Invocation 是會(huì)話域,它持有調(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
     *
     * 獲取對(duì)應(yīng)的invoker對(duì)象
     *
     * @return invoker.
     * @transient
     */
    Invoker<?> getInvoker();

}

3.2.1 類圖

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

3.3 Result

com.alibaba.dubbo.rpc.Result

Result 是會(huì)話域,它持有調(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 中針對(duì)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等方法 都是獲取但會(huì)的隱式參數(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

過濾器接口,和我們平時(shí)理解的 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ù)時(shí)調(diào)用。
     *
     * @param <T>
     * @param proxy Service對(duì)象
     * @param type  Service接口類型
     * @param url   Service對(duì)應(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)一個(gè)服務(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)我們?cè)跇I(yè)務(wù)代理調(diào)用 Service 的方法時(shí),透明的內(nèi)部轉(zhuǎn)換成調(diào)用 Invoker 的 #invoke(Invocation) 方法
  • 服務(wù)提供者暴露服務(wù)的 主過程 如下圖:

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

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

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

Dubbo 協(xié)議的 Invoker 轉(zhuǎn)為 Exporter 發(fā)生在 DubboProtocol 類的 export 方法,它主要是打開 socket 偵聽服務(wù),并接收客戶端發(fā)來的各種請(qǐng)求,通訊細(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é)議在接受請(qǐng)求時(shí),應(yīng)該記錄請(qǐng)求的來源地址:RpcContext.getContext().setRemoteAddress();<br>
     * 2. export()必須是冪等的,也就是說,在暴露服務(wù)時(shí),一次調(diào)用和兩次調(diào)用時(shí)沒有區(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對(duì)象的invoke()方法時(shí),協(xié)議需要相應(yīng)地執(zhí)行Invoker對(duì)象的Invoke()方法
     * 2. 實(shí)現(xiàn)由`refer()`返回的`Invoker`是協(xié)議的責(zé)任。一般來說,協(xié)議在`Invoker`實(shí)現(xiàn)中發(fā)送遠(yuǎn)程請(qǐng)求。
     * 3. 當(dāng)url中設(shè)置了 check = false時(shí),連接失敗時(shí)不能拋出異常,且只能內(nèi)部消化。
     *
     * @param <T>  Service type 服務(wù)的類型
     * @param type Service class 服務(wù)的 class對(duì)象
     * @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ù)提供方失敗時(shí),拋出該異常。
     */
    @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上的對(duì)象。

/**
 * 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.
     *
     * 獲取對(duì)應(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)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容