dubbo源碼分析24 -- 調用核心 Invoke

任何框架或組件,總會有核心領域模型,比如:Spring 的 Bean,Struts 的 Action,Napoli 的 Queue 。對於 Dubbo 來說它的核心就是 Service(服務接口),而 Service 不管是 provider 暴露服務,還是 consumer 引用服務。它都是一個非常重要的概念,我們來看一下 Dubbo 的核心領域模型:

  • Protocol 是服務域,它是 Invoker 暴露和引用的主功能入口,它負責 Invoker 的生命週期管理。
  • Invoker 是實體域,它是 Dubbo 的核心模型,其它模型都向它靠擾,或轉換成它,它代表一個可執行體,可向它發起 invoke 調用,它有可能是一個本地的實現,也可能是一個遠程的實現,也可能一個集羣實現。
  • Invocation 是會話域,它持有調用過程中的變量,比如方法名,參數等。

1、dubbo 服務暴露

服務提供者暴露一個服務的詳細過程。

dubbo_rpc_export.jpg

上圖是服務提供者暴露服務的主過程:

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

Dubbo 處理服務暴露的關鍵就在 Invoker 轉換到 Exporter 的過程,上圖中的紅色部分。下面我們以 Dubbo 和 RMI 這兩種典型協議的實現來進行說明:

Dubbo 的實現

Dubbo 協議的 Invoker 轉爲 Exporter 發生在 DubboProtocol 類的 export 方法,它主要是打開 socket 偵聽服務,並接收客戶端發來的各種請求,通訊細節由 Dubbo 自己實現。

RMI 的實現

RMI 協議的 Invoker 轉爲 Exporter 發生在 RmiProtocol類的 export 方法,它通過 Spring 或 Dubbo 或 JDK 來實現 RMI 服務,通訊細節這一塊由 JDK 底層來實現,這就省了不少工作量。

2、dubbo 服務暴露

服務消費者消費一個服務的詳細過程。

dubbo_rpc_refer.jpg

上圖是服務消費的主過程:

首先 ReferenceConfig 類的 init 方法調用 Protocol 的 refer 方法生成 Invoker 實例(如上圖中的紅色部分),這是服務消費的關鍵。接下來把 Invoker 轉換爲客戶端需要的接口(如:HelloWorld)。

關於每種協議如 RMI/Dubbo/Web service 等它們在調用 refer 方法生成 Invoker 實例的細節和上一章節所描述的類似。

3、滿眼都是 Invoker

由於 Invoker 是 Dubbo 領域模型中非常重要的一個概念,很多設計思路都是向它靠攏。這就使得 Invoker 滲透在整個實現代碼裏,對於剛開始接觸 Dubbo 的人,確實容易給搞混了。 下面我們用一個精簡的圖來說明最重要的兩種 Invoker:服務提供 Invoker 和服務消費 Invoker:

dubbo_rpc_invoke.jpg

爲了更好的解釋上面這張圖,我們結合服務消費和提供者的代碼示例來進行說明:

服務消費者代碼:

public class DemoClientAction {

    private DemoService demoService;

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

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

上面代碼中的 DemoService 就是上圖中服務消費端的 proxy,用戶代碼通過這個 proxy 調用其對應的 Invoker,而該 Invoker 實現了真正的遠程服務調用。

服務提供者代碼:

public class DemoServiceImpl implements DemoService {

    public String sayHello(String name) throws RemoteException {
        return "Hello " + name;
    }
}

上面這個類會被封裝成爲一個 AbstractProxyInvoker 實例,並新生成一個 Exporter 實例。這樣當網絡通訊層收到一個請求後,會找到對應的 Exporter 實例,並調用它所對應的 AbstractProxyInvoker 實例,從而真正調用了服務提供者的代碼。Dubbo 裏還有一些其他的 Invoker 類,但上面兩種是最重要的。

參考文章:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章