dubbo源碼分析24 -- 調(diào)用核心 Invoke

任何框架或組件,總會(huì)有核心領(lǐng)域模型,比如:Spring 的 Bean,Struts 的 Action,Napoli 的 Queue 。對(duì)于 Dubbo 來(lái)說(shuō)它的核心就是 Service(服務(wù)接口),而 Service 不管是 provider 暴露服務(wù),還是 consumer 引用服務(wù)。它都是一個(gè)非常重要的概念,我們來(lái)看一下 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)用過(guò)程中的變量,比如方法名,參數(shù)等。

1、dubbo 服務(wù)暴露

服務(wù)提供者暴露一個(gè)服務(wù)的詳細(xì)過(guò)程。

dubbo_rpc_export.jpg

上圖是服務(wù)提供者暴露服務(wù)的主過(guò)程:

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

Dubbo 處理服務(wù)暴露的關(guān)鍵就在 Invoker 轉(zhuǎn)換到 Exporter 的過(guò)程,上圖中的紅色部分。下面我們以 Dubbo 和 RMI 這兩種典型協(xié)議的實(shí)現(xiàn)來(lái)進(jìn)行說(shuō)明:

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

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

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

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

2、dubbo 服務(wù)暴露

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

dubbo_rpc_refer.jpg

上圖是服務(wù)消費(fèi)的主過(guò)程:

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

關(guān)于每種協(xié)議如 RMI/Dubbo/Web service 等它們?cè)谡{(diào)用 refer 方法生成 Invoker 實(shí)例的細(xì)節(jié)和上一章節(jié)所描述的類似。

3、滿眼都是 Invoker

由于 Invoker 是 Dubbo 領(lǐng)域模型中非常重要的一個(gè)概念,很多設(shè)計(jì)思路都是向它靠攏。這就使得 Invoker 滲透在整個(gè)實(shí)現(xiàn)代碼里,對(duì)于剛開始接觸 Dubbo 的人,確實(shí)容易給搞混了。 下面我們用一個(gè)精簡(jiǎn)的圖來(lái)說(shuō)明最重要的兩種 Invoker:服務(wù)提供 Invoker 和服務(wù)消費(fèi) Invoker:

dubbo_rpc_invoke.jpg

為了更好的解釋上面這張圖,我們結(jié)合服務(wù)消費(fèi)和提供者的代碼示例來(lái)進(jìn)行說(shuō)明:

服務(wù)消費(fèi)者代碼:

public class DemoClientAction {

    private DemoService demoService;

    public void setDemoService(DemoService demoService) {
        this.demoService = demoService;
    }

    public void start() {
        String hello = demoService.sayHello("world" + i);
    }
}

上面代碼中的 DemoService 就是上圖中服務(wù)消費(fèi)端的 proxy,用戶代碼通過(guò)這個(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ù)提供者的代碼。Dubbo 里還有一些其他的 Invoker 類,但上面兩種是最重要的。

參考文章:

最后編輯于
?著作權(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),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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