Dubbo源碼分析之服務暴露

1、Dubbo服務暴露過程

    下圖是Dubbo官網的一個服務提供者暴露服務的主過程:上圖是服務提供者暴露服務的主過程:app

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

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

Dubbo 的實現

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

RMI 的實現

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

解析服務

在ServiceConfig.export()或ReferenceConfig.get()初始化時,將Bean對象轉換暴露服務或請求服務的URL,全部Bean屬性轉成URL的參數。spa

而後將URL傳給Protocol擴展點,基於擴展點的Adaptive機制,根據URL的協議頭,進行不一樣協議的服務暴露或引用。code

 

url參數列只有group,interface,version是服務的匹配條件,三者決定是否是同一個服務,其它配置項均爲調優和治理參數對象

暴露服務

有註冊中心配置:<dubbo:registry address="zookeeper://10.20.153.10:2181" />get

ServiceConfig解析出的URL的格式爲:io

registry://registry-host/com.alibaba.dubbo.registry.RegistryService?export=URL.encode("dubbo://service-host/com.foo.FooService?version=1.0.0")

1)基於擴展點的Adaptive機制,經過URL的"registry://"協議頭識別,就會調用RegistryProtocol的export()方法,將export參數中的提供者URL,先註冊到註冊中心,再從新傳給Protocol擴展點進行暴露:

dubbo://service-host/com.foo.FooService?version=1.0.0

2)基於擴展點的Adaptive機制,經過提供者URL的"dubbo://"協議頭識別,就會調用DubboProtocol的export()方法,打開服務端口。

 

Invoker<?> invoker = proxyFactory.getInvoker(ref, (Class) interfaceClass, url);

Exporter<?> exporter = protocol.export(invoker);

具體服務àInvoker àExporter  Exporter是負載打開服務端口等待請求。

引用服務

註冊中心配置:<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")

基於擴展點的Adaptive機制,經過URL的"registry://"協議頭識別,就會調用RegistryProtocol的refer()方法,基於refer參數中的條件,查詢提供者URL,如:

dubbo://service-host/com.foo.FooService?version=1.0.0

基於擴展點的Adaptive機制,經過提供者URL的"dubbo://"協議頭識別,就會調用DubboProtocol的refer()方法,獲得提供者引用。

而後RegistryProtocol將多個提供者引用,經過Cluster擴展點,假裝成單個提供者引用返回。

invoker = refprotocol.refer(interfaceClass, urls.get(0));

(T) proxyFactory.getProxy(invoker);

 

攔截服務

基於ProtocolFilterWrapper類,將全部Filter組裝成鏈,在鏈的最後一節調用真實的引用。

基於ProtocolListenerWrapper類,將全部InvokerListener和ExporterListener組裝集合,在暴露和引用先後,進行回調。

包括監控在內,全部附加功能,所有經過Filter攔截實現。

  • 用戶自定義filter默認在內置filter以後。
  • 特殊值default,表示缺省擴展點插入的位置。
    • 好比:filter="xxx,default,yyy",表示xxx在缺省filter以前,yyy在缺省filter以後。
  • 特殊符號-,表示剔除。
    • 好比:filter="-foo1",剔除添加缺省擴展點foo1。
    • 好比:filter="-default",剔除添加全部缺省擴展點。
  • provider和service同時配置的filter時,累加全部filter,而不是覆蓋。
    • 好比:<dubbo:provider filter="xxx,yyy"/>和<dubbo:service filter="aaa,bbb" />,則xxx,yyy,aaa,bbb均會生效。
    • 若是要覆蓋,需配置:<dubbo:service filter="-xxx,-yyy,aaa,bbb" />
相關文章
相關標籤/搜索