dubbo源碼之四——dubbo服務發布


dubbo版本:2.5.4

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

服務發布方在spring的配置文件中配置如下:

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

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

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

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

 

ServiceBean除了繼承dubbo自己的配置抽象類(ServiceConfig)以外,還實現了一系列的spring接口用來參與到spring容器的啟動以及bean的創建過程中去。由於spring實例化的ServiceBean是單例模式的,在Spring的容器ApplicationContext的啟動過程refresh過程中最后第二步會預先初始化單例的bean, 在bean的初始化過程會設置beanName,   設置容器applicationContext, 回調   InitializingBean的afterPropertiesSet。

最后一步finishRefresh會觸發ContextRefreshedEvent事件, 而ServiceBean實現了ApplicationListener接口監聽了此事件, 而在之前一步實例化的ServiceBean注冊了這個事件,所以ServiceBean的onApplicationEvent(ApplicationEvent event)方法被觸發, 在這個方法中觸發了export方法來暴露服務。

 

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

1. loadRegistries(true)

checkRegistry如果xml中沒有配置注冊中,從dubbo.properties中讀取配置,構建RegistryConfig對象並賦值

構建注冊中心URL統一數據模式集合List<registryUrl>

2. 因為dubbo支持多協議配置,遍歷所有協議分別根據不同的協議把服務export到不同的注冊中心上去

a) 判斷是否是泛型暴露

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

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

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對象

 

官方文檔服務發布序列圖

 

 

發布活動圖

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM