Dubbo源碼分析(11):服務發佈

服務發佈是服務提供方向註冊中註冊服務過程,以便服務消費者從註冊中心查閱並調用服務。

服務發佈方在spring的配置文件中配置以下:git

<bean id="demoService"class="com.alibaba.dubbo.demo.provider.DemoServiceImpl" />

上面是在spring中配置的服務的具體實現,是spring中的一個普通的beangithub

<dubbo:serviceinterface="com.alibaba.dubbo.demo.DemoService" ref=」demoService」/>

上面的配置spring容器在啓動的過程當中會解析自定義的schema元素dubbo轉換成實際的配置實現ServiceBean ,並把服務暴露出去。spring

 

ServiceConfig.doExportUrls()執行具體的export過程

 

1. loadRegistries(true)緩存

checkRegistry若是xml中沒有配置註冊中,從dubbo.properties中讀取配置,構建RegistryConfig對象並賦值app

構建註冊中心URL統一數據模式集合List<registryUrl>負載均衡

2. 由於dubbo支持多協議配置,遍歷全部協議分別根據不一樣的協議把服務export到不一樣的註冊中心上去ide

a) 判斷是不是泛型暴露ui

b) 根據協議構建暴露服務的統一數據模型URL編碼

c) 配置的了monitor加載monitor,並給URL設置MONITOR_KEYurl

d) 給註冊中regitryUrl設置EXPORT_KEY值爲前面構建的暴露服務url

e) 根據服務具體實現,實現接口以及regitryUrl從代理工廠ProxyFactory獲取代理Invoker(繼承於AbstractProxyInvoker),它是對具體實現的一種代理

f) Protocol.export(invoker) 暴露服務invoker

Invoker包含上一步傳入的RegistryUrl, registryUrl的protocol值爲registry

ProtocolListenerWrapper和ProtocolFilterWrapper對於協議爲REGISTRY_PROTOCOL直接跳過,最終由RegistryProtocol處理export的過程

 

RegistryProtocol暴露服務過程

這裏傳入的Invoker是由RegistryUrl從ProxyFactory獲得的Invoker

1. 從Invoker獲取providerUrl,在獲取cacheKey, 根據cacheKey獲取本地緩存的ExporterChangeableWrapper(exporter代理,創建返回的exporter與protocol export出的exporter的對應關係), 若是存在返回。

2. 若是不存在,根據傳入的 Invoker獲取providerUrl, 在構建InvokerDelegete(originInvoker, providerUrl)

3. Protocol.exprot(invokerDelegete) 根據providerUrl 的協議(通常是dubbo協議)經過Protocol的設配類暴露務,獲得exporter

4. 利用providerUr導出的exporter和invoker構建對象ExporterChangeableWrapper緩存到本地

5. 由Invoker獲得registryUrl。

 在根據registryUrl從RegistryFactory獲取Registry, 獲取RegistryUrl的註冊中心協議,這裏咱們拿zooKeeper協議爲例。由dubbo的擴展機制獲得的是ZookeeperRegistryFactory,獲得註冊器爲ZookeeperRegistry

6. 由Invoker獲取ProviderUrl在去除不須要在註冊中心看到的字段獲得registryProviderUrl

7. 註冊中心(ZookeeperRegistry)註冊registryProviderUrl

Registry.register(registryProviderUrl)

8. 由registryProviderUrl獲取overrideSubscribeUrl,在構建OverrideListener

9. registry.subscribe(overrideSubscribeUrl, overrideSubscribeListener) 註冊中心訂閱這個url, 用來當數據變化通知從新暴露, 哪zookeeper爲例,暴露服務會在zookeeper生成一個節點,當節點發生變化的時候會觸發overrideSubscribeListener的notify方法從新暴露服務

10.      構建並返回一個新的exporter實例

 

DubboProtocol暴露服務的過程

1. 從invoker獲取統一數據模型url

2. 由url構建serviceKey(通常由端口,接口名,版本,group分組)

如:com.alibaba.dubbo.demo.DemoService:20880 這個是由接口和端口組成的

3. 構建DubboExporter放入本地map作緩存

4. 根據url openserver。 查找本地緩存以key爲url.getAddress若是沒有ExchangeServer建立。設置heartbeat時間,設置編碼解碼協議

根據url和ExchangeHandler  綁定server並返回(具體如何綁定專題介紹)

5. 返回DubboExporter對象

 

官方文檔序列圖

註冊/註銷服務
服務的註冊與註銷,是對服務提供方角色而言,那麼註冊服務與註銷服務的時序圖,如圖所示:

服務訂閱/取消
爲了知足應用系統的需求,服務消費方的可能須要從服務註冊中心訂閱指定的有服務提供方發佈的服務,在獲得通知可使用服務時,就能夠直接調用服務。反過來,若是不須要某一個服務了,能夠取消該服務。
下面看一下對應的時序圖,如圖所示:

服務消費方發起遠程調用的底層通訊

服務提供方接收請求並響應的底層通訊

 

協議支持
Dubbo支持多種協議,以下所示:

  • Dubbo協議
  • Hessian協議
  • HTTP協議
  • RMI協議
  • WebService協議
  • Thrift協議
  • Memcached協議
  • Redis協議

在通訊過程當中,不一樣的服務等級通常對應着不一樣的服務質量,那麼選擇合適的協議即是一件很是重要的事情。你能夠根據你應用的建立來選擇。例如,使用RMI協議,通常會受到防火牆的限制,因此對於外部與內部進行通訊的場景,就不要使用RMI協議,而是基於HTTP協議或者Hessian協議。

參考補充
Dubbo以包結構來組織各個模塊,各個模塊及其關係,如圖所示:

能夠經過Dubbo的代碼(使用Maven管理)組織,與上面的模塊進行比較。簡單說明各個包的狀況:

  • dubbo-common 公共邏輯模塊,包括Util類和通用模型。
  • dubbo-remoting 遠程通信模塊,至關於Dubbo協議的實現,若是RPC用RMI協議則不須要使用此包。
  • dubbo-rpc 遠程調用模塊,抽象各類協議,以及動態代理,只包含一對一的調用,不關心集羣的管理。
  • dubbo-cluster 集羣模塊,將多個服務提供方假裝爲一個提供方,包括:負載均衡、容錯、路由等,集羣的地址列表能夠是靜態配置的,也能夠是由註冊中心下發。
  • dubbo-registry 註冊中心模塊,基於註冊中心下發地址的集羣方式,以及對各類註冊中心的抽象。
  • dubbo-monitor 監控模塊,統計服務調用次數,調用時間的,調用鏈跟蹤的服務。
  • dubbo-config 配置模塊,是Dubbo對外的API,用戶經過Config使用Dubbo,隱藏Dubbo全部細節。
  • dubbo-container 容器模塊,是一個Standalone的容器,以簡單的Main加載Spring啓動,由於服務一般不須要Tomcat/JBoss等Web容器的特性,不必用Web容器去加載服務。

參考連接

相關文章
相關標籤/搜索