Dubbo 服務導出過程

Dubbo 服務導出過程

dubbo採用 URL 作爲配置信息的統一格式,所有擴展點都通過傳遞 URL 攜帶配置信息,通過上一篇文章:

dubbo源碼實現之SPI 和自適應擴展點 中我們可以瞭解到dubbo是如何確保擴展點一定可以獲取到url的

URL 是 Dubbo 配置的載體,通過 URL 可讓 Dubbo 的各種配置在各個模塊之間傳遞

如下是一個使用dubbo協議發佈服務的url:

dubbo://192.168.99.1:20880/com.gupaoedu.dubbo.ISayHelloService?anyhost=true&application=springboot-dubbo-provider
&bean.name=ServiceBean:com.gupaoedu.dubbo.ISayHelloService&bind.ip=192.168.99.1&bind.port=20880&cluster=failsafe&deprecated=false&dubbo=2.0.2
&dynamic=true&generic=false&interface=com.gupaoedu.dubbo.ISayHelloService&methods=sayHello&pid=21932&qos-enable=false&register=true&release=2.7.2
&side=provider&timeout=50000&timestamp=1582010821966

 

起點:

Dubbo 服務導出過程始於 Spring 容器發佈刷新事件,Dubbo 在接收到事件後,會立即執行服務導出邏輯

 

流程概述:組裝url --》 導出服務 --》 註冊服務

整個邏輯大致可分爲三個部分

(1)第一部分是前置工作,主要用於檢查參數,組裝 URL

(2)第二部分是導出服務,包含導出服務到本地 (JVM),和導出服務到遠程兩個過程

(3)第三部分是不同的協議實例向註冊中心註冊服務,用於服務發現(例如dubbo協議會去zookeeper上註冊一個節點)

注意:導出服務到遠程包括導出服務(不是導出到本地)和註冊服務兩個步驟

爲什麼發佈遠程服務需要兩步呢?

首先我們需要明白註冊中心的功能是什麼,註冊中心只是一個記錄,一個用於記錄有哪些ip地址和端口提供了哪些服務的記錄中心,其不會承擔和客戶端進行通信和提供服務的功能

也就是說我們想要發佈一個遠程服務給客戶端調用,註冊中心只是負責提供服務端的門牌號的功能,具體的通信還是需要服務端自己來做,什麼意思呢?

就是說服務端和客戶端的網絡IO操作還是服務端進行維護的,而dubbo默認是使用netty來實現遠程通信的,因此導出遠程服務的作用實際上就是利用Netty的遠程通信能力,來打開一個端口等待接收來自客戶端的請求

 

源碼分析:

服務導出的入口方法是 ServiceBean 的 onApplicationEvent。onApplicationEvent 是一個事件響應方法,該方法會響應Spring 容器刷新事件,在收到 Spring 上下文刷新事件後執行服務導出操作

ServiceBean 是 Dubbo 與 Spring 框架進行整合的關鍵,可以看做是兩個框架之間的橋樑。具有同樣作用的類還有 ReferenceBean

關鍵類:

RegistryProtocol :此類的作用是將協議url註冊到註冊中心

protocol的export()方法被調用之前,會經過什麼呢?

當一個protocol的export()方法被調用之前,會首先經過其包裝類的層層方法,在這些包裝類中執行一系列的操作之後纔會調用到真正的protocol的export()方法,如下所示:

如圖所示:

(1)首先會經過Protocol$Adaptive的export方法,在其中會解析url中的protocol參數的值,然後從IOC容器中找到真正的protocol(被QoSProtocolWrapper包裝的protocol)

(2)然後經過QoSProtocolWrapper的export()方法,QoSProtocolWrapper用於給運維人員添加操作的空間

(3)經過 ProtocolFilterWrapper的export()方法,ProtocolFilterWrapper是protocol攔截器鏈上的一個攔截器

 

服務的發佈做了哪些事情

1.基於spring進行解析配置文件存儲到ServiceConfig

2.各種判斷邏輯,保證配置信息安全性

3.組裝url(registry:// --> zookeeper:// --> dubbo:// --> injvm://)

4.構建一個invoker(動態代理)

5.RegistryProtocol.export()(註冊服務到註冊中心)

6.各種wrapper(Protocol$Adapter、filterWrapper,QosProtocolWrapper,listener)

7.DubboProtocol.export()發佈服務,創建ExchangeServer ,調用bind()方法,進入Transporters 的bind方法,默認是NettyTransporter(使用Netty進行底層通信)

8.啓動一個NettyServer(這裏就接上了netty的內容,具體就是使用主從reactor線程模型來處理客戶端的請求)

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章