天天看點

服務過載保護設計與實施

一、概述

過載保護是微服務系統無法繞過的技術難題,本文對過載保護的原因、解決方案、實施與測試閉環進行全流程的研究。

過載後如果不進行保護,會導緻資源耗盡,進而導緻雪崩。過載有很多原因,大緻如下:

(1)資源不足,例如cpu、記憶體、io、存儲空間、PID不足;

(2)設計缺陷,例如代碼邏輯問題導緻處理效率低;

(3)幾率性業務重合,例如很多高io業務集中到一個節點上;

(4)使用者側突發壓力,例如大量使用者在同一時間使用相同功能;

(5)異常業務場景壓力增加,例如補償類的業務造成雙倍壓力,清理政策失效導緻檔案量激增;

(6)下遊服務異常導緻上遊業務阻塞,例如網絡/存儲io緩慢導緻上遊業務壓力變大;

從軟體外部故障和系統測試故障分析,因過載導緻的故障占了很大比例,可以說過載是無法避免的問題。本文不讨論業務邏輯,僅讨論的是過載本身的通用解決方案。

二、解決方案

下圖是過載保護的幾種手段,第1種是通過提高服務能力解決壓力不夠的問題;第2/3/4種都屬于服務降級,即犧牲一部分服務能力;第5種熔斷是為了防止壓力傳導(同時也能防止故障傳導);三者之間是不沖突的。

服務過載保護設計與實施

當發生過載時,首先考慮的是通過增加資源,這樣做可以提高服務能力,但也面臨很多問題:

(1)資源投入增大,如果是突發壓力,會使資源平均使用率下降;

(2)伸展之後還要考慮收縮;

(3)彈縮時機和業務行為強相關,政策不好選擇,容易導緻延遲伸縮和誤判;

(4)能力有上限。

當發生過載之後,服務降級是最經濟、高效的手段,可以有效避免服務完全不可用和雪崩,利用有限的資源提供最大的服務能力。

服務降級有很多政策、方法,主要包含如下三種:

1、關閉非核心業務

在資源有效的情況下,保留核心業務、關閉非核心業務是一種常用手段,這種方法很合理,但是實施比較複雜,一方面要提前識别哪些是核心業務、哪些是非核心業務,另一方面,不好評估關閉非核心業務會降低多少壓力,以及何時恢複非核心業務。是以關閉非核心業務經常使用手動方式,手動埋點、手動打開/關閉開關。

2、限流

微服務架構下很多服務都是單一功能,不适合關閉非核心業務,是以限流成為主流方法。設定一個線程池/消息隊列,超出隊列直接拒絕,進而減輕服務的壓力。

在實際項目程中,為了應對突發壓力,往往會在執行隊列的基礎上再增加一個緩沖隊列,超出執行隊列後先放入緩沖隊列,少量突發壓力會先放入緩沖隊列,緩沖隊列也滿了才會拒絕。

3、降低一緻性

降低一緻性是一種特殊的服務降級方法,方式有很多(包括上面的緩沖隊列也是其中一種)。

(1)同步改為異步,強一緻性改為最終一緻性

這裡主要指請求方的同步改異步,請求發出去之後,等待時間T之後如果沒有收到傳回值,則不再等待,并給使用者傳回“請求已經送出,由于系統繁忙,需要排隊執行,請勿重複操作。”

這種方式實時性得不到保障,一緻性也是通過事務完整性來保障的,不适用所有業務,需要根據實際業務情況選擇。

異步隻能解決突發壓力增加,如果長時間壓力大,下遊任務依然會積壓,最終無法執行成功。并且,如果實作最終一緻性,任務失敗後會做重試,重試本身又會增加系統壓力。

(2)增加緩沖隊列

緩沖隊列主要用來應對突發壓力,當執行隊列滿了之後,先把請求存入緩存隊列。緩沖隊列隻是“權宜”之計,超出隊列的請求依然要進行限流。實際運用中,緩沖隊列和限流是不沖突的。

緩沖隊列一般使用FIFO的方式進行存取。緩沖隊列設定太短起不到很好的效果,會很快充滿。設定過長,又會導緻部分請求等待時間過長,這些請求執行完成傳回給上遊時已經逾時,上遊服務認為這是無效請求(此情況隻會出現在上遊是同步請求的場景)。這種情況持續一段時間後,每個請求都會逾時。是以隊列的長度設計要适中,還要考慮實際業務規律。

(3)多副本強一緻性,改為主用同步、備用異步

這是一種特殊場景。

根據CAP原則,一緻性、可用性、分區數三者必須犧牲一個,在滿足CP的業務場景下,除了可用性下降之外,還會導緻響應時間增加、對底層壓力貢獻增加,這時可以通過政策修改一緻性,修改為主用同步、備用異步。

總結:降低一緻性的三種方式都是為了解決突發壓力,第二種方法是常用方法,第一種方法可以和第二種方法配合使用,第一種方法适用範圍有限,要根據實際業務決定是否采用。

服務過載保護設計與實施

如上圖所示,服務A向服務B發請求,當請求出現大量逾時、失敗、拒絕時,上遊服務A應該停止發送請求,這種行為稱為熔斷。熔斷可以減少對下遊施加的壓力,也可以防止下遊故障向上遊傳導。

不難看出,服務降級是指當服務壓力過大時,本服務通過減少工作量來降低壓力,而熔斷是通過減少無效請求來降低下遊壓力,二者的差別主要是實施對象不一樣。

三、落地

下圖為閉環流程:

服務過載保護設計與實施

先由項目架構師給出統一的設計原則,然後由産品架構師進行設計、DEV進行開發、測試人員進行測試,然後進行疊代改進。

通過前面的分析,我們對設計原則給出如下使用建議:

1、有性能風險的服務,必須要有彈性,支援垂直或水準彈縮。(現狀:水準彈縮目前失效性不滿足要求,垂直彈縮場景java微服務的記憶體無法收縮。)

2、有性能風險的服務,必須要有服務降級能力,關閉非核心業務和限流二選一,降低一緻性建議選用緩沖隊列,隊列長度設定适中,同步/異步要根據實際業務需求選擇。(現狀:目前沒發現關閉非核心業務的微服務,部分業務進行了限流,緩沖隊列長度未嚴格要求。)

3、熔斷建議全部使用。(現狀:目前基本都沒使用)

4、注意:開發團隊根據以上原則進行方案設計、開發,針對彈縮、限流、熔斷等功能,建議從架構給出解決方案,開發團隊隻需要根據自己的業務特點填寫模闆參數即可。

設計階段需要給出各項名額,包括彈性伸縮的門檻值、彈性伸縮的時間名額、業務并發度名額、緩沖隊列長度、熔斷門檻值和熔斷檢測周期。這些名額是開發的依據,也是測試的依據。

根據設計進行開發。

根據4.2設計的進行測試驗證,驗證既要包含功能是否實作,又要包含效率是否達成。

1、彈性能力驗證

(1)垂直彈縮,驗證業務閑時資源資源使用率不超過request,忙時超過request但達不到limit。

(2)水準彈縮,驗證點是是否能彈、是否能縮,以及時效性是否滿足名額要求

2、并發度驗證

白盒測試主要在FT覆寫,通過打樁的方式對執行隊列和緩沖隊列進行壓測。

黑盒測試是從業務視角看,執行隊列和緩沖隊列是無法區分的,可以逐漸增加并發度,看最大并發度是多少。

并發度測試的時候,還要關注①在過負荷的時候是否會限流;②進入隊列的任務是否能夠全部成功;③長時間過負荷測試服務是否會崩潰。

3、熔斷功能驗證

熔斷的測試方式包含幾部分:

(1)下遊挂了之後,上遊請求一直失敗,上遊服務是否會熔斷;

(2)上遊請求逾時,是否會熔斷;

(3)熔斷開啟狀态,在下遊恢複之後,能不能通過有效的檢測機制恢複上遊業務。

1、前端接口級過載測試

針對微服務接口級的測試,要設計相應的壓力測試,測試标準參考為3.4測試分析。

2、後端名額類過載測試

針對名額文檔中的高并發類名額,後端設計相應的業務并發測試,參考3.4測試分析的第2節并發度驗證。

繼續閱讀