如何實施異構伺服器的負載均衡及過載保護?

2021-09-23 06:37:50 字數 3740 閱讀 2497

零、需求緣起

第一篇文章「一分鐘了解負載均衡」和大家share了網際網路架構中反向**層、站點層、服務層、資料層的常用負載均衡方法。

第二篇文章「lvs為何不能完全代替dns輪詢」和大家share了網際網路接入層負載均衡需要解決的問題及架構演進。

在這兩篇文章中,都強調了「負載均衡是指,將請求/資料【均勻】分攤到多個操作單元上執行,負載均衡的關鍵在於【均勻】」。

然而,後端的service有可能部署在硬體條件不同的伺服器上:

1)如果對標最低配的伺服器「均勻」分攤負載,高配的伺服器的利用率不足;

2)如果對標最高配的伺服器「均勻」分攤負載,低配的伺服器可能會扛不住;

能否根據異構伺服器的處理能力來動態、自適應進行負載均衡及過載保護,是本文要討論的問題。

一、service層的負載均衡通常是怎麼做的

「一分鐘了解負載均衡」中提到,service層的負載均衡,一般是通過service連線池來實現的,呼叫方連線池會建立與下游服務多個連線,每次請求「隨機」獲取連線,來保證service訪問的均衡性。

「rpc-client實現細節」中提到,負載均衡、故障轉移、超時處理等細節也都是通過呼叫方連線池來實現的。

這個呼叫方連線池能否實現,根據service的處理能力,動態+自適應的進行負載排程呢?

二、通過「靜態權重」標識service的處理能力

呼叫方通過連線池元件訪問下游service,通常採用「隨機」的方式返回連線,以保證下游service訪問的均衡性。

要打破這個隨機性,最容易想到的方法,只要為每個下游service設定乙個「權重」,代表service的處理能力,來調整訪問到每個service的概率,例如:

假設service-ip1,service-ip2,service-ip3的處理能力相同,可以設定weight1=1,weight2=1,weight3=1,這樣三個service連線被獲取到的概率分別就是1/3,1/3,1/3,能夠保證均衡訪問。

假設service-ip1的處理能力是service-ip2,service-ip3的處理能力的2倍,可以設定weight1=2,weight2=1,weight3=1,這樣三個service連線被獲取到的概率分別就是2/4,1/4,1/4,能夠保證處理能力強的service分別到等比的流量,不至於資源浪費。

使用nginx做反向**與負載均衡,就有類似的機制。

這個方案的優點是:簡單,能夠快速的實現異構伺服器的負載均衡。

缺點也很明顯:這個權重是固定的,無法自適應動態調整,而很多時候,伺服器的處理能力是很難用乙個固定的數值量化。

三、通過「動態權重」標識service的處理能力

提問:通過什麼來標識乙個service的處理能力呢?

回答:其實乙個service能不能處理得過來,能不能響應得過來,應該由呼叫方說了算。呼叫服務,快速處理了,處理能力跟得上;呼叫服務,處理超時了,處理能力很有可能跟不上了。

動態權重設計

1.用乙個動態權重來標識每個service的處理能力,預設初始處理能力相同,即分配給每個service的概率相等;

2.每當service成功處理乙個請求,認為service處理能力足夠,權重動態+1

3.每當service超時處理乙個請求,認為service處理能力可能要跟不上了,權重動態-10(權重下降會更快)

4.為了方便權重的處理,可以把權重的範圍限定為[0, 100],把權重的初始值設為60分

舉例說明:

假設service-ip1,service-ip2,service-ip3的動態權重初始值weight1=weight2=weight3=60,剛開始時,請求分配給這3臺service的概率分別是60/180,60/180,60/180,即負載是均衡的。

隨著時間的推移,處理能力強的service成功處理的請求越來越多,處理能力弱的service偶爾有超時,隨著動態權重的增減,權重可能變化成了weight1=100,weight2=60,weight3=40,那麼此時,請求分配給這3臺service的概率分別是100/200,60/200,40/200,即處理能力強的service會被分配到更多的流量。

四、過載保護

提問:什麼是過載保護?

圖示:無過載保護的負載與處理能力圖(會掉底)

回答:網際網路軟體架構設計中所指的過載保護,是指當系統負載超過乙個service的處理能力時,如果service不進行自我保護,可能導致對外呈現處理能力為0,且不能自動恢復的現象。而service的過載保護,是指即使系統負載超過乙個service的處理能力,service讓能保證對外提供有損的穩定服務。

圖示:有過載保護的負載與處理能力圖(不會掉底)

提問:如何進行過載保護?

回答:最簡易的方式,服務端設定乙個負載閾值,超過這個閾值的請求壓過來,全部拋棄。這個方式不是特別優雅。

五、如何借助「動態權重」來實施過載保護

動態權重是用來標識每個service的處理能力的乙個值,它是rpc-client客戶端連線池層面的乙個東東。服務端處理超時,客戶端rpc-client連線池都能夠知道,這裡只要實施一些策略,就能夠對「疑似過載」的伺服器進行降壓,而不用伺服器「拋棄請求」這麼粗暴的實施過載保護。

應該實施一些什麼樣的策略呢,例如:

1.如果某乙個service的連線上,連續3個請求都超時,即連續-10分三次,客戶端就可以認為,伺服器慢慢的要處理不過來了,得給這個service緩一小口氣,於是設定策略:接下來的若干時間內,例如1秒(或者接下來的若干個請求),請求不再分配給這個service;

2.如果某乙個service的動態權重,降為了0(像連續10個請求超時,中間休息了3次還超時),客戶端就可以認為,伺服器完全處理不過來了,得給這個service喘一大口氣,於是設定策略:接下來的若干時間內,例如1分鐘(為什麼是1分鐘,根據經驗,此時service一般在發生fullgc,差不多1分鐘能回過神來),請求不再分配給這個service;

3.可以有更複雜的保護策略…

這樣的話,不但能借助「動態權重」來實施動態自適應的異構伺服器負載均衡,還能在客戶端層面更優雅的實施過載保護,在某個下游service快要響應不過來的時候,給其喘息的機會。

需要注意的是:要防止客戶端的過載保護引起service的雪崩,如果「整體負載」已經超過了「service集群」的處理能力,怎麼轉移請求也是處理不過來的,還得通過拋棄請求來實施自我保護。

六、總結

1.service的負載均衡、故障轉移、超時處理通常是rpc-client連線池層面來實施的

2.異構伺服器負載均衡,最簡單的方式是靜態權重法,缺點是無法自適應動態調整

3.動態權重法,可以動態的根據service的處理能力來分配負載,需要有連線池層面的微小改動

4.過載保護,是在負載過高時,service為了保護自己,保證一定處理能力的一種自救方法

5.動態權重法,還可以用做service的過載保護

如何實施異構伺服器的負載均衡及過

1 service的負載均衡 故障轉移 超時處理 通常是rpc client連線池層面來實施的 2 異構伺服器負載均衡,最簡單的方式是靜態權重法,缺點是無法自適應動態調整 3 動態權重法,可以動態的根據service的處理能力來分配負載,需要有連線池層面的微小改動 4 過載保護,是在負載過高時,se...

如何實施異構伺服器的負載均衡及過載保護?

後端的service有可能部署在硬體條件不同的伺服器上 1 如果對標最低配的伺服器 均勻 分攤負載,高配的伺服器的利用率不足 2 如果對標最高配的伺服器 均勻 分攤負載,低配的伺服器可能會扛不住 能否根據異構伺服器的處理能力來動態 自適應進行負載均衡及過載保護,是本文要討論的問題。一 service...

異構伺服器的負載均衡及過載保護

需求緣起 後端的service有可能部署在硬體條件不同的伺服器上 1 如果對最低配的伺服器 均勻 分攤負載,高配的伺服器的利用率不足 2 如果對最高配的伺服器 均勻 分攤負載,低配的伺服器可能會扛不住 能否根據異構伺服器的處理能力來動態 自適應進行負載均衡及過載保護。一 service層的負載均衡通...