(轉)dubbo遠程調用細節


作者: 白文志 (來自開源社區)

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

上圖是服務提供者暴露服務的主過程:
首先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底層來實現,這就省了不少工作量。

 

 

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

 

上圖是服務消費的主過程:
首先ReferenceConfig類的init方法調用Protocol的refer方法生成Invoker實例(如上圖中的紅色部分),這是服務消費的關鍵。接下來把Invoker轉換為客戶端需要的接口(如:HelloWorld)。
關於每種協議如RMI/Dubbo/Web service等它們在調用refer方法生成Invoker實例的細節和上一章節所描述的類似。

滿眼都是Invoker

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

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

服務消費者代碼

 

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(DubboInvoker、 HessianRpcInvoker、 InjvmInvoker、 RmiInvoker、 WebServiceInvoker中的任何一個),而該Invoker實現了真正的遠程服務調用

 

服務提供者代碼
public class DemoServiceImpl implements DemoService {
 
    public String sayHello(String name) throws RemoteException {
        return "Hello " + name;
    }
 
}

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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM