任何框架或組件,總會(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ò)程。

上圖是服務(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ò)程。

上圖是服務(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:

為了更好的解釋上面這張圖,我們結(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 類,但上面兩種是最重要的。
參考文章: