負載均衡
通俗來講就是一個選擇的問題,在叢集環境中,不可能每次都讓一個伺服器都來處理所有的請求,當消費者呼叫服務時,客戶端會選擇,也必須選擇一個伺服器來進行處理,考慮各伺服器的負載,來進行分壓,避免單個伺服器響應同一請求,容易造成伺服器宕機、崩潰等問題。
主要是向外暴露的一個介面:loadBalance,位於dubbo的cluster包下,可見該介面是專門用於管理叢集的,方法中也只存在一個方法:
透過select方法,從眾多的Invoker(dubbo封裝的類,代表客戶端的呼叫者)選擇出一個呼叫者,URL就是呼叫者發起的URL請求連結,從這個URL中可以獲取很多請求的具體資訊,Invocation表示的是呼叫的具體過程。
同時dubbo實現了一個抽象類AbstractLoadBlance,實現介面LoadBalance,而該抽象類AbstractLoadBalance的各個子類,便實現了dubbo的負載均衡策略。
在抽象類AbstractLoadBalance中,實現了介面LoadBalance的select方法:
在方法中實現了呼叫者的判斷,如非空、單一服務,通過後呼叫真正的doSelect方法,從而獲取服務。
而doSelect方法是一個抽象方法,意味著具體的策略均由繼承該抽象類的子類來實現,該父類在select中只進行服務者的校驗。
另外,在AbstractLoadBalance中,實現了getWeight方法,顧名思義,該方法用於獲取服務的權重:
首先透過呼叫者的URL(URL為Invoker實體中的一個屬性,同樣由dubbo封裝而成)獲取基本的權重,如果權重大於0,會獲取服務啟動時間,再用當前的時間-啟動時間就是服務到目前為止運行了多久,因此這個upTime就可以理解為服務啟動時間,再獲取配置的預熱時間,如果啟動時間小於預熱時間,就會再次呼叫獲取權重。這個預熱的方法其實dubbo針對JVM做出的一個很契合的最佳化,因為JVM從啟動到起來都執行到最佳狀態是需要一點時間的,這個時間叫做warmup,而dubbo就會對這個時間進行設定,然後等到服務執行時間和warmup相等時再計算權重,這樣就可以保障服務的最佳執行狀態!
再看下這個圖,dubbo實現了4種負載均衡策略,分別是:
RandomLoadBalance(隨機呼叫);
RoundRobinLoadBlance(輪詢呼叫);
LeastActiveLoadBlance(最少活躍數呼叫);
ConsistentHashLoadBalance(一致性Hash演算法);
這裡就只說一下dubbo的預設負載均衡策略RandomLoadBalance,也就是隨機呼叫。
為什麼說該策略是dubbo的預設策略呢。這裡我們就得回到LoadBalance介面的原始碼上看了。
LoadBalance介面同時擁有一個@SPI的註解,該註解標註了dubbo的預設策略為RandomLoadBalance:
基於AbstractLoadBalance抽象類,該策略子類重寫了父類的doSelect方法,在方法中,會首先遍歷每個提供服務的機器,透過父類的getWeight方法,獲取每個服務的權重,然後累加權重值,判斷每個服務的提供者權重是否相同。
如果每個呼叫者的權重不相同,並且每個權重大於0,那麼就會根據權重的總值生成一個隨機數,再用這個隨機數,根據呼叫者的數量每次減去呼叫者的權重,直到計算出當前的服務提供者隨機數小於0,就選擇那個提供者。
另外,如果每個機器的權重的都相同,那麼權重就不會參與計算,直接選擇隨機演算法生成的某一個選擇,完全隨機。原始碼:
如果說在業務場景中,不希望使用該策略,也可以透過註解@Reference來指定使用dubbo的哪一個負載均衡策略:
@Reference(loadbalance="roundrobin")
其中“roundrobin”為實現子類中的常量NAME,便可以指定使用策略RoundRobinLoadBlance(輪詢呼叫)。
基於篇幅就不再一一介紹另外幾個策略,有興趣的可以看dubbo原始碼,一起進步~
負載均衡
通俗來講就是一個選擇的問題,在叢集環境中,不可能每次都讓一個伺服器都來處理所有的請求,當消費者呼叫服務時,客戶端會選擇,也必須選擇一個伺服器來進行處理,考慮各伺服器的負載,來進行分壓,避免單個伺服器響應同一請求,容易造成伺服器宕機、崩潰等問題。
dubbo的負載均衡主要是向外暴露的一個介面:loadBalance,位於dubbo的cluster包下,可見該介面是專門用於管理叢集的,方法中也只存在一個方法:
透過select方法,從眾多的Invoker(dubbo封裝的類,代表客戶端的呼叫者)選擇出一個呼叫者,URL就是呼叫者發起的URL請求連結,從這個URL中可以獲取很多請求的具體資訊,Invocation表示的是呼叫的具體過程。
同時dubbo實現了一個抽象類AbstractLoadBlance,實現介面LoadBalance,而該抽象類AbstractLoadBalance的各個子類,便實現了dubbo的負載均衡策略。
在抽象類AbstractLoadBalance中,實現了介面LoadBalance的select方法:
在方法中實現了呼叫者的判斷,如非空、單一服務,通過後呼叫真正的doSelect方法,從而獲取服務。
而doSelect方法是一個抽象方法,意味著具體的策略均由繼承該抽象類的子類來實現,該父類在select中只進行服務者的校驗。
另外,在AbstractLoadBalance中,實現了getWeight方法,顧名思義,該方法用於獲取服務的權重:
首先透過呼叫者的URL(URL為Invoker實體中的一個屬性,同樣由dubbo封裝而成)獲取基本的權重,如果權重大於0,會獲取服務啟動時間,再用當前的時間-啟動時間就是服務到目前為止運行了多久,因此這個upTime就可以理解為服務啟動時間,再獲取配置的預熱時間,如果啟動時間小於預熱時間,就會再次呼叫獲取權重。這個預熱的方法其實dubbo針對JVM做出的一個很契合的最佳化,因為JVM從啟動到起來都執行到最佳狀態是需要一點時間的,這個時間叫做warmup,而dubbo就會對這個時間進行設定,然後等到服務執行時間和warmup相等時再計算權重,這樣就可以保障服務的最佳執行狀態!
具體負債均衡策略再看下這個圖,dubbo實現了4種負載均衡策略,分別是:
RandomLoadBalance(隨機呼叫);
RoundRobinLoadBlance(輪詢呼叫);
LeastActiveLoadBlance(最少活躍數呼叫);
ConsistentHashLoadBalance(一致性Hash演算法);
這裡就只說一下dubbo的預設負載均衡策略RandomLoadBalance,也就是隨機呼叫。
為什麼說該策略是dubbo的預設策略呢。這裡我們就得回到LoadBalance介面的原始碼上看了。
LoadBalance介面同時擁有一個@SPI的註解,該註解標註了dubbo的預設策略為RandomLoadBalance:
@SPI(RandomLoadBalance.class)public interface LoadBalance{ //...}RandomLoadBalance(隨機呼叫)基於AbstractLoadBalance抽象類,該策略子類重寫了父類的doSelect方法,在方法中,會首先遍歷每個提供服務的機器,透過父類的getWeight方法,獲取每個服務的權重,然後累加權重值,判斷每個服務的提供者權重是否相同。
如果每個呼叫者的權重不相同,並且每個權重大於0,那麼就會根據權重的總值生成一個隨機數,再用這個隨機數,根據呼叫者的數量每次減去呼叫者的權重,直到計算出當前的服務提供者隨機數小於0,就選擇那個提供者。
另外,如果每個機器的權重的都相同,那麼權重就不會參與計算,直接選擇隨機演算法生成的某一個選擇,完全隨機。原始碼:
如果說在業務場景中,不希望使用該策略,也可以透過註解@Reference來指定使用dubbo的哪一個負載均衡策略:
@Reference(loadbalance="roundrobin")
其中“roundrobin”為實現子類中的常量NAME,便可以指定使用策略RoundRobinLoadBlance(輪詢呼叫)。
基於篇幅就不再一一介紹另外幾個策略,有興趣的可以看dubbo原始碼,一起進步~