1. 服務導出的入口方法
2. 服務導出原理
2.1 重新整理配置參數
2.1 确定協定,生成URL
2.3 啟動對應協定的伺服器
2.4 向注冊中心注冊服務
2.6 監聽動态配置修改
通過在服務實作類上面加上@Service注解,Dubbo可以掃描并生成兩個bean對象:Spring中的bean 和 ServiceBean,然後把服務導出到zookeeper、redis等注冊中心!
上一篇文章中通過源碼,我們明白了 ServiceBean的生成過程, 那麼Dubbo是如何進行服務導出的呢?ServiceBean由于實作了ApplicationListener<ContextRefreshedEvent>,釋出了一個容器重新整理事件,意味着在spring容器啟動完畢後,會調用onApplicationEvent方法,在方法内部調用export()向注冊中心暴露服務!源碼如下:
服務導出:主要是指 服務提供者向注冊中心上提供服務的過程

Dubbo的服務導出主要做以下幾件事情
根據配置方式的優先級,重新整理Dubbo配置參數
确定協定,生成URL
根據服務的參數資訊,啟動對應的網絡伺服器(netty、tomcat、jetty等),用來接收網絡請求
将服務的資訊注冊到注冊中心
啟動監聽器,監聽動态配置修改
一個Dubbo服務的配置參數有多種,比如version、group、delay、weight等等,這些配置參數的配置方式也有多種,而Dubbo選擇配置方式的優先級從高到低如圖所示,高優先級的配置覆寫低優先級的配置
Dubbo使用一個LinkedList集合來儲存各種配置方式的配置資訊,因為LinkedList是有序集合,友善後續對配置按優先級順序進行覆寫和更新,源碼如下所示:
有發現上面源碼中缺失了@Service()中的配置了嗎?Dubbo對@Service()上的配置優先級進行了特殊處理
我們可以自定義isConfigCenterFirst的屬性,決定@Service()上的配置優先級
最後周遊LinkedList集合中的元素(配置方式),進行配置資訊覆寫和更新
從以上分析我們可以看出,在服務導出之前,首先得确定服務的參數。服務的參數除開來自于服務的自身配置外,還可以來自比自身優先級高的配置。是以在确定服務參數時,需要先從上級擷取參數,擷取之後,如果服務本身配置了相同的參數,那麼則進行覆寫
如果不同優先級之間沒有出現沖突,則會互補。比如:@Service本身沒有配置timeout參數,但是如果服務所屬的應用的properties配置檔案配置了timeout,那麼這個應用下的服務都會繼承這個timeout配置。
一個服務可以配置多個協定:
源碼中會周遊所有的協定,每一種協定導出一個單獨的服務
有了确定的協定,服務名,服務參數後,自然就可以組裝成服務的URL了,在doExportUrlsFor1Protocol()方法中組裝服務URL
有了準确的服務URL之後,就可以把URL注冊到注冊中心上去了,在注冊之前,還需要獲得注冊中心的URL
注意:上面所說的服務URL或者注冊中心URL,并不是浏覽器上的url連接配接位址,而是一個名為URL的類,類内部封裝了端口号、ip、協定等注冊資訊,如下所示
Dubbo在與其他元件互動的時候,會使用在服務URL中指定的協定,根據不同的協定啟動不同的伺服器,比如:
Http協定就啟動Tomcat、Jetty。
Dubbo協定就啟動Netty。
不能隻啟動Server,還需要綁定一個RequestHandler,用來處理請求。
比如,Http協定對應的就是InternalHandler。Dubbo協定對應的就是ExchangeHandler。
源碼中方法如下:
有了服務URL 和 注冊中心的位址的URL,就可以向zookeeper注冊服務,注冊失敗的話會進行重試!
如上2.1中的配置,可以在zookeeper中生成兩個服務
以dubbo協定的url為例,把dubbo協定的url通過編解碼工具,解碼後得到:
dubbo://192.168.100.1:20880/org.apache.dubbo.demo.DemoService?anyhost=true&application=dubbo-demo-provider1-application&bean.name=ServiceBean:org.apache.dubbo.demo.DemoService&deprecated=false&dubbo=2.0.2&dynamic=true&generic=false&interface=org.apache.dubbo.demo.DemoService&logger=log4j&methods=sayHello&pid=12236&release=2.7.0&side=provider&timestamp=1614435347611&token=tulingtoken
可以看到注冊到zookeeper上的服務其實就是這個服務配置的全部資訊,其中token的主要作用是:調用服務時,為了分辨是否從zookeeper上拉取的服務!
服務在導出的過程中需要向動态配置中心的資料進行訂閱,以便當管理人員修改了動态配置中心中對應服務的參數後,服務提供者能及時做出變化。
服Dubbo如果使用的是zookeeper作為配置中心,那麼服務配置就存儲在zookeeper節點上,就需要利用Zookeeper的Watcher機制,監聽的是節點變化。是以在一個服務進行導出時,需要在服務提供者端給目前服務生成一個對應的監聽器執行個體,這個監聽器執行個體為OverrideListener,它負責監聽對應服務的動态配置變化,并且根據動态配置中心的參數重寫服務URL。
當動态配置中心修改了某個服務的配置後,就會觸發OverrideListener中的notify對注冊中心的URL進行重寫覆寫,相當于重新釋出服務,實作實時釋出服務