Dubbo預熱和延遲暴露


dubbo有四種負載均衡的方式:

1)RandomLoadBalance:加權隨機算法

2)LeastActiveLoadBalance:最小活躍負載均衡

3)ConsistentHashLoadBalance:一致性hash負載均衡

4)RoundRobinLoadBalance:加權輪詢負載均衡

dubbo的負載均衡策略,主體對外暴露的是一個接口:LoadBalance。

在dubbo中所有的負載均衡實現類都繼承自AbstractLoadBalance,該類實現了LoadBalance接口,並封裝了一些公共的邏輯。

負載均衡的入口方法:

 

還有些共用方法,如服務提供者權重計算邏輯:

 

上面是權重的計算過程,該過程主要用於保證當服務運行時長小於服務預熱時間時,對服務進行降權,避免讓服務在啟動之初就處於高負載狀態。服務預熱是一個優化手段,與此類似的還有 JVM 預熱。主要目的是讓服務啟動后“低功率”運行一段時間,使其效率慢慢提升至最佳狀態。

我對比了一下

我們在使用的dubbo版本中的getweight方法和官方最新的有一點出入

 

 

github fix地址:https://github.com/apache/incubator-dubbo/commit/ed66afd9a38d80f839f0381fbd1dc1d3c068bc1c#diff-c5cb2df641f0a7d0553343c757425d2b

修正了預熱時間戳的錯誤,添加“remote”。用戶端url的時間戳鍵

我們現在使用的dubbo版本,這個bug依然存在

 

我們來研究一下 Dubbo 導出服務的過程。

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

整個邏輯大致可分為三個部分,

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

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

第三部分是向注冊中心注冊服務,用於服務發現

接下來我們重點看一下,dubbo的一個優化點——延遲暴露

 

什么是延遲暴露呢

dubbo service默認是在容器啟動的時候暴露的,暴露之后,消費者就可以調用服務提供者,但是如果此時服務提供者需要一定的時間初始化一些資源,那么就可以選擇延遲暴露。比如在容器啟動之后延遲10S再暴露。
 
設置延遲暴露的方法:
xml配置:
服務提供者端:<dubbo:provider delay="20000"/>
消費者端:<dubbo:service interface="com.xxx.xxxService" ref="xxxService" delay="3000"/>
既在標簽內加一個delay參數 單位是毫秒
 
 

 

在沒有設置延遲暴露或者設置delay = -1的情況下,服務導出的入口方法是 ServiceBean 的 onApplicationEvent方法(bean初始化完成時)

在設置延遲暴露的情況下,服務導出的入口方法是 ServiceBean 的afterPropertiesSet方法(bean開始初始化的時候)

 

注:官方文檔里面寫的是服務導出的入口方法是 ServiceBean 的 onApplicationEvent。

afterPropertiesSet()是ServiceBean繼承自InitializingBean的方法,是在初始化bean的時候被調用,

onApplicationEvent()是ServiceBean繼承自ApplicationListener的方法,是bean被初始化完成的時候被調用。

先調用afterPropertiesSet(),在調用onApplicationEvent(),在設置延遲暴露的情況下,會直接走afterPropertiesSet()中的export(),官方文檔此處不嚴謹。

 

下面來看下具體的實現流程:

afterPropertiesSet()會根據條件來決定是否暴露服務。

在完成一些變量的初始化之后,會根據是否設置了delay屬性來決定是否暴露

 

 

 

注:現在解釋一下 supportedApplicationListener 變量含義,該變量用於表示當前的 Spring 容器是否支持 ApplicationListener,這個值初始為 false。在 Spring 容器將自己設置到 ServiceBean 中時,ServiceBean 的 setApplicationContext 方法會檢測 Spring 容器是否支持 ApplicationListener。若支持,則將 supportedApplicationListener 置為 true。

 

如果設置了delay屬性,則會在afterPropertiesSet()進入export(),在export()進行服務的導出。

 

如果沒有設置delay屬性,則會在bean初始化完成之后,在刷新容器最后一步發布ContextRefreshEvent事件的時候,通知實現了ApplicationListener的類進行回調onApplicationEvent,dubbo會在這個方法中發布服務。

 

 

此處 我們使用的dubbo版本有一個bug

 

在properties文件中

如果設置了delay ,按照邏輯是要先delay在doexport()

而解析JVM參數的邏輯(appendProperties(this);)是在doExport()方法中調用;

所以導致 if (delay != null && delay > 0)判斷時,還沒有解析JVM參數delay=5000,從而導致這種配置在properties文件中不起作用;

 

在github上面發現作者有修復這個bug

fix地址:https://github.com/cnn112002/incubator-dubbo/commit/0fe72a6f0390ff3673fb1d94f682629ea9fbc28c

 


免責聲明!

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



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