過載保護+異構服務器的負載均衡,怎么設計?
負載均衡是指,將請求/數(shù)據(jù)分攤到多個操作單元上執(zhí)行,關鍵在于均衡。
然而,后端的服務器有可能硬件條件不同:
- 如果對標低配的服務器“均勻”分攤負載,高配的服務器利用率會不足
- 如果對標高配的服務器“均勻”分攤負載,低配的服務器會扛不住
能否根據(jù)異構服務器的處理能力來動態(tài)、自適應進行負載均衡,以及過載保護呢?
負載均衡通常是怎么做的?
service層的負載均衡,一般是通過service連接池來實現(xiàn)的,調用方連接池會建立與下游服務多個連接,每次請求“隨機”獲取連接,來保證訪問的均衡性。
負載均衡、故障轉移、超時處理等細節(jié)也都是通過調用方連接池來實現(xiàn)的。
調用方連接池能否,根據(jù)service的處理能力,動態(tài)+自適應的進行負載調度呢?
(1) 方案一:可以通過“靜態(tài)權重”標識service的處理能力。
最容易想到的方法,可以為每個下游service設置一個“權重”,代表service的處理能力,來調整訪問到每個service的概率,如上圖所示:
- 假設ip1,ip2,ip3的處理能力相同,可以設置weight1=1,weight2=1,weight3=1,這樣三個service連接被獲取到的概率分別就是1/3,1/3,1/3,能夠保證均衡訪問;
- 假設ip1的處理能力是ip2,ip3的處理能力的2倍,可以設置weight1=2,weight2=1,weight3=1,這樣三個service連接被獲取到的概率分別就是2/4,1/4,1/4,能夠保證處理能力強的service分到等比的流量,不至于資源浪費;
Nginx就具備類似的能力。
- 方案優(yōu)點:簡單粗暴,能夠快速的實現(xiàn)異構服務器的負載均衡。
- 方案缺點:權重是固定的,無法自適應動態(tài)調整,而很多時候,服務器的處理能力是很難用一個固定的數(shù)值量化。
(2) 方案二:通過“動態(tài)權重”標識service的處理能力。
如何來標識一個service的處理能力呢?
服務能不能處理得過來,該由調用方說了算:
- 調用服務,快速處理,處理能力跟得上
- 調用服務,處理超時,處理能力很有可能跟不上了
如何來設計動態(tài)權重?
可以這么玩:
- 用一個動態(tài)權重,來標識每個service的處理能力,默認初始處理能力相同,即分配給每個service的概率相等;
- 每當service成功處理一個請求,認為service處理能力足夠,權重動態(tài)+1;
- 每當service超時處理一個請求,認為service處理能力可能要跟不上了,權重動態(tài)-10;
畫外音:
權重下降,會比權重上升更快。
為了方便權重的處理,可以把權重的范圍限定為[0, 100],把權重的初始值設為60分。
舉例說明:
假設service-ip1,service-ip2,service-ip3的動態(tài)權重初始值:
- weight1=60
- weight2=60
- weight3=60
剛開始時,請求分配給這3臺service的概率分別是60/180,60/180,60/180,即負載是均衡的。
隨著時間的推移:
- 處理能力強的service成功處理的請求越來越多
- 處理能力弱的service偶爾有超時
隨著動態(tài)權重的增減,權重會發(fā)生變化:
- weight1=100
- weight2=60
- weight3=40
那么此時,請求分配給這3臺service的概率分別是100/200,60/200,40/200,即處理能力強的service會被分配到更多的流量。
那什么是過載保護?
如上圖所示,如果沒有過載保護:
- 隨著外部負載的不斷升高,系統(tǒng)實際處理負載會增加
- 外部負載升高到一個臨界值,系統(tǒng)會被壓垮,實際處理能力會降為0
畫外音:這就是所謂的“掉底”。
過載保護,是指當外部負載超過系統(tǒng)處理能力時,系統(tǒng)會進行自我保護,依然能對外提供有損的穩(wěn)定服務。
如上圖所示,如果進行了過載保護:
- 隨著外部負載的不斷升高,系統(tǒng)實際處理負載會增加
- 外部負載即使超過一個臨界值,系統(tǒng)不會被壓垮,而能保持一定的處理能力
畫外音:外部負載***大,系統(tǒng)也不會“掉底”。
那如何進行過載保護?
(1) 方案一:可以通過“靜態(tài)權重”標識service的處理能力。
這是最簡易的方式,服務端設定一個負載閾值,超過這個閾值的請求壓過來,全部拋棄。
畫外音:這個方式不是特別優(yōu)雅。
(2) 方案二:借助“動態(tài)權重”來實施過載保護。
如同異構服務器負載均衡,仍然通過:
- 成功處理加分(+1)
- 處理超時扣分(-10)
這種動態(tài)權重,來標識后端的處理能力。
畫外音:仍然是在連接池層面實現(xiàn)的。
當一個服務端屢次處理超時,權重不斷降低時,連接池只要實施一些策略,就能夠對“疑似過載”的服務器進行降壓,而不用服務器“拋棄請求”這么粗暴的實施過載保護。
應該實施什么樣的策略,來對“疑似過載”的服務器進行降壓保護呢?
可以這么玩:
(1) 如果某一個服務器,連續(xù)3個請求都超時,即連續(xù)-10分三次,就可以認為,服務器處理不過來了,得給這個服務器喘一小口氣,于是設定策略:接下來的若干時間內,例如1秒,負載不再分配給這個服務器;
畫外音:休息1秒后,再分給它。
(2) 如果某一個service的動態(tài)權重,降為了0(休息了3次還超時),就可以認為,服務器完全處理不過來了,得給這個服務器喘一大口氣,于是設定策略:接下來的若干時間內,例如1分鐘,請求不再分配給這個服務器;
畫外音:根據(jù)經(jīng)驗,此時服務器一般在fullGC,差不多1分鐘能回過神來。
這樣的話,不但能借助“動態(tài)權重”來實施動態(tài)自適應的異構服務器負載均衡,還能在客戶端層面更優(yōu)雅的實施過載保護,在某個下游服務器快要響應不過來的時候,給其喘息的機會。
過載保護要注意什么問題?
要防止過載保護引起服務器的雪崩,如果“整體負載”已經(jīng)超過了“服務器集群”的處理能力,怎么轉移請求也是處理不過來的。這時,還是得通過拋棄請求來實施自我保護。
總結
- 負載均衡、故障轉移、超時處理通常是連接池層面來實施的
- 異構服務器負載均衡,最簡單的方式是靜態(tài)權重法,缺點是無法自適應動態(tài)調整
- 動態(tài)權重法,可以動態(tài)的根據(jù)服務器的處理能力來分配負載,需要有連接池層面的微小改動
- 過載保護,是在負載過高時,服務器為了保護自己,保證一定處理能力的一種自救方式
- 動態(tài)權重法,還可以用做服務器的過載保護
【本文為51CTO專欄作者“58沈劍”原創(chuàng)稿件,轉載請聯(lián)系原作者】