下圖是Dubbo官網的一個服務提供者暴露服務的主過程:上圖是服務提供者暴露服務的主過程:app
首先 ServiceConfig
類拿到對外提供服務的實際類 ref(如:HelloWorldImpl),而後經過 ProxyFactory
類的 getInvoker
方法使用 ref 生成一個 AbstractProxyInvoker
實例,到這一步就完成具體服務到 Invoker
的轉化。接下來就是 Invoker
轉換到 Exporter
的過程。socket
Dubbo 處理服務暴露的關鍵就在 Invoker
轉換到 Exporter
的過程,上圖中的紅色部分。下面咱們以 Dubbo 和 RMI 這兩種典型協議的實現來進行說明:ide
Dubbo 協議的 Invoker
轉爲 Exporter
發生在 DubboProtocol
類的 export
方法,它主要是打開 socket 偵聽服務,並接收客戶端發來的各類請求,通信細節由 Dubbo 本身實現。ui
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攔截實現。