天天看點

伺服器過載保護(上篇)——過載介紹2 過載後果3 過載原因4 過載預防5 過載保護

  本文由騰訊WeTest團隊提供,更多資訊可直接戳連結檢視:http://wetest.qq.com/lab/

  微信号:TencentWeTest

1 何為過載

“過載”一詞,在海量服務的背景開發中,基本都會遇到。何為過載,即目前負載已經超過了系統的最大處理能力。例如,系統每秒能夠處理的請求是100個,但實際每秒的請求量卻是1000個,就可以判定系統出現了過載。

過載的定義看似簡單,但卻是處理過載問題的關鍵。對于任何其他問題,同樣得抓住問題的本質,方可不偏離問題核心,萬變而不離其宗。

2 過載後果

“過載”的出現,會導緻部分服務不可用,如果處置不當,極有可能引起服務完全不可用,乃至雪崩。

我們的系統中,由于是單線程狀态機的處理模式,順序處理所有連結的緩沖區消息,當出現處理能力的下降或者請求量大幅增加,導緻處理能力小于請求量的情況下,消息就會在系統緩沖區中堆積,造成消息處理的延遲會持續增加,在正式環境中,連結數目較多,系統緩沖區較大,最終會導緻消息處理延遲大到不可接受的程度,最終會導緻處理的都是無效消息,造成服務不可用。

當然具體的業務需要具體的分析,把握住問題的影響,才能夠做到一切盡在掌握,根據“墨菲定律”,通常對後果的判斷不應過于樂觀,謹慎行事、考慮充分才能夠做到胸有成竹。

3 過載原因

“過載”的出現,不同系統模型的具體原因都會有所不同,例如CPU跑滿,頻繁讀寫導緻IO瓶頸,記憶體耗盡,請求量突增等等。但究其根本原因,可以歸結為兩點:

1、處理能力的下降;

2、請求量的上升。

隻有對自身系統的有更深層和透徹的了解,才能更好地考慮如何處置問題。“頭疼醫頭,腳疼醫腳”的處理問題方式,隻能解決一時之需,對症下藥,才是解決問題的根本之道。

任何問題的保護行為可以依據事件發生的階段分為:

1、 發生前,預防;

2、 發生時,處置;

3、 發生後,恢複。

但在保護的措施中,都和業務的模型有着相關性,沒有完全統一的方案,适合自己的才是最好的。

4 過載預防

在過載發生前的預防,就需在系統設計之初,依據具體的業務模型可以考慮預防過載的措施:

1、 優化服務處理流程,降低處理資源消耗,提升自身處理能力;例如CPU消耗型服務,是否可以考慮優化算法,提升處理能力。

2、 分離處理子產品;将負載分擔到不同的子產品或者伺服器;例如IO是瓶頸的服務,考慮是否可以将IO子產品進行分離。

3、 負載均衡;将請求量分流,降低單服請求量。

4、 輕重子產品分離;重要子產品單獨部署和處理,防止子產品之間的互相影響。

5、 前端防禦;在前端控制請求頻率,緩解後端壓力;例如用戶端可以做保護措施,控制聊天頻率,點選操作失敗,可以延時一段時間,才允許使用者繼續點選;前端服務發現後端出現過載問題,可選擇性拒絕服務,降低後端壓力。

6、 使用緩沖區;緩沖區的使用,可以幫我們抵擋請求量的抖動,但緩沖區的使用同樣也有很多技巧,并非越大越好。首先需要考慮記憶體,cpu等資源的開銷,業務的模型是否需要這麼大的緩沖區。例如緩沖區過大,處理完整個緩沖區,都需要幾十秒,而前端等待逾時則為幾秒,那麼每次處理緩沖區的内容,都是舊的,前端認為都是逾時,服務完全不可用。另外是後端卻又處理成功,會導緻系統資訊不對稱,進而導緻更為嚴重的問題,例如,在遊戲中購買道具的場景,前端扣使用者的錢,認為逾時失敗而不給使用者發對應的物品,後端卻又執行成功了,嚴重營運問題就此産生。

7、 做好監控,及時告警;例如當CPU達到80%時,當處理請求超出一定門檻值時,及時告警,做好擴容,優化等其他準備。

當然依據業務模型的不同,還有很多預防的措施,依然是前述做到知底,才能夠找出适合自身的方法。

5 過載保護

處理過載的方法有許多,适用于不同的業務場景,并無絕對的最優方案,合适的才是最好的,但能比對上“合适”一詞,是對系統整體和經驗的一個考驗。下面介紹一些常用的處理方案以及我們是如何做的:

Ø 請求量門檻值控制

在系統部署上線之前,預估好系統的處理能力,限定最大同時能夠處理的請求量、流量或者連結數。當請求量快接近于最大處理能力時,則告警,超過範圍,則觸發拒絕請求機制。由此可見對于門檻值的設定是一個很關鍵的環節,門檻值過高,依然可能導緻過載,門檻值過低,則又導緻負載上不去。門檻值的設定也會是一個不斷調優的過程。該方法的優點和缺陷都很明顯。

優點:識别和處理簡單;

缺點:門檻值的設定需要一定的經驗,會有一定的難度,同時如果處理能力發生變化時,門檻值就很難動态發生變化。

Ø 監控系統資源

伺服器監控CPU,記憶體等資源的使用情況,設定門檻值,超出門檻值,則可以認為過載,進而觸發拒絕請求機制。

優點:使用動态的資源資料,從相對根本的原因上識别過載,而無需過多關心具體的業務處理;

缺點:一是處理相對複雜;二是在某些場景下,資源資料的耗盡并不意味着出現過載的情況。例如服務開了較大的記憶體池,看起來記憶體資源耗盡了,實際上負載是足夠的,又如現在都是多核伺服器跑着多程序或者多線程的服務,單一的CPU耗盡也不能夠代表服務就出現過載,但又可能産生過載,這就和具體業務有關;三是在某些場景下,出現過載的情況,也不一定會耗盡資源,例如目前所有的服務都在等待之中(可能是後端的回複或者其他),同樣也不會對CPU、記憶體、io、網絡等資源造成影響,但依然進入了過載。總體來說該方式适合的場景相對會簡單點。

Ø 檢測請求到達時間

依據請求處理的時延來判斷是否過載。記錄請求到達的時間戳,和處理請求結束的時間戳,得到請求到達自身伺服器處理的時延,超出門檻值,則可判定為逾時失效,可以直接丢棄。使用獨立子產品讀取系統緩沖區中資料,打上時間戳,存入消息緩沖區,在處理時,超過一定時延的請求,則拒絕處理,因為可以認為即使處理了也是無用的。從中可以看出時間戳很關鍵(為啥會單獨提出這個問題,因為在後續的方案設計中,時間戳依然是解決過載問題的關鍵點,此處先賣個關子)。

A、 時間戳如果使用本地讀取時刻調用系統的時間函數擷取,就沒有考慮消息包到達系統緩沖區的時間,是以是萬萬不能這樣做。

B、 到可以通過ioctl調用SIOCGSTAMP的接口,獲得時間戳,但這會加大系統開銷,原因是每次recv完,都需要重新設定一下ioctl一次。并且不是線程安全的。

C、 使用socket選項SO_TIMESTAMP,通過帶外資料擷取到資料到達系統緩沖區的時間。

其處理方式如下圖所示:

伺服器過載保護(上篇)——過載介紹2 過載後果3 過載原因4 過載預防5 過載保護

通過這種方式已經能夠很好地解決負載問題,通過如此,并不需要設定過于繁瑣的配置或者去識别過載的問題,目前此方法在SPP的架構中在使用。個人覺得可能存在的一些問題在于:

1、 完全使用時間戳過期的方式來判斷,并不一定适合所有場景,假設處理耗時過長,而在緩沖區中也呆了較長時間,但請求量并不大,伺服器未過載,在處理一些需要強寫入的情況下,單靠該機制也會稍許欠妥。但如果加入一些協定上層機制,告訴該消息務必執行,也是可避免的。

2、 在出現過載的情況之下,很可能會導緻整體的服務都會産生一個固定的延時,因為每次抛棄到可執行的範圍内,至少會有一個逾時時間範圍内的延時,如果是較長的服務鍊的話,最前面的等待服務很可能會出現逾時,是以其延時的設定相對也很困難,過小就太過靈敏,過大就會出現剛所述的問題。

伺服器過載保護(上篇)——過載介紹2 過載後果3 過載原因4 過載預防5 過載保護

3、 該方式隻是管理了到達本伺服器緩沖區之後的問題,并沒有考慮整條服務鍊上的延時,很可能到達本伺服器緩沖區時,就已經過期了,并且有可能這些資料在對端緩沖區已經産生了堆積,但到本端,并不會判斷其過期。

4、 剩下還有一些内容可以做更多優化:另外SO_TIMESTAMP使用的是系統時間,會受系統時間修改的影響,但這個問題也不大,因為即使修改了,影響的隻是本次系統緩沖區的資料。其他可以考慮業務的輕重程度,做按服務來丢棄。

  本文由騰訊WeTest團隊提供,更多資訊可直接戳連結檢視: http://wetest.qq.com/lab/

  微信号:TencentWeTest

繼續閱讀