dubbo客戶端:
根據配置檔案請求服務端
查詢服務端方式:直接查詢、註冊中心查詢
直接查詢:在配置檔案中直接配置服務端地址和實現介面 在沒有註冊中心,直連提供者的情況下(例如:<dubbo:reference url="dubbo://service-host/com.foo.FooService?version=1.0.0" />),ReferenceConfig 解析出的 URL 的格式為:dubbo://service-host/com.foo.FooService?version=1.0.0。 基於擴充套件點自適應機制,通過 URL 的 dubbo:// 協議頭識別,直接呼叫 DubboProtocol 的 refer() 方法,返回提供者引用。
註冊中心查詢:通過註冊中心找到服務端地址和實現介面 在有註冊中心,
1、通過註冊中心發現提供者地址的情況下 (例如:<dubbo:registry address="zookeeper://10.20.153.10:2181" />),ReferenceConfig 解析出的 URL 的格式為: registry://registry-host/com.alibaba.dubbo.registry.RegistryService?refer=URL.encode("consumer://consumer-host/com.foo.FooService?version=1.0.0")。 2、基於擴充套件點自適應機制,通過 URL 的 registry:// 協議頭識別,就會呼叫 RegistryProtocol 的 refer() 方法,基於 refer 引數中的條件,查詢提供者 URL,如: dubbo://service-host/com.foo.FooService?version=1.0.0。
3、基於擴充套件點自適應機制,通過提供者 URL 的 dubbo:// 協議頭識別,就會呼叫 DubboProtocol 的 refer() 方法,得到提供者引用。
然後 RegistryProtocol 將多個提供者引用,通過 Cluster 擴充套件點,偽裝成單個提供者引用返回。
客戶端消費過程:
1、首先 ReferenceConfig 類的 init 方法呼叫 Protocol 的 refer 方法生成 Invoker 例項(如上圖中的紅色部分),這是服務消費的關鍵。
2、接下來把 Invoker 轉換為客戶端需要的介面(如:HelloWorld)。 關於每種協議如 RMI/Dubbo/Web service 等它們在呼叫 refer 方法生成 Invoker 例項:
Dubbo 的實現 Dubbo 協議的 Invoker 轉為 Exporter 發生在 DubboProtocol 類的 export 方法,它主要是開啟 socket 偵聽服務,並接收客戶端發來的各種請求,通訊細節由 Dubbo 自己實現。
RMI 的實現
RMI 協議的 Invoker 轉為 Exporter 發生在 RmiProtocol類的 export 方法,它通過 Spring 或 Dubbo 或 JDK 來實現 RMI 服務,通訊細節這一塊由 JDK 底層來實現,這就省了不少工作量。
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 類,但上面兩種是最重要的。