當流量突變時,系統中的負載保護如何應對?

有人說:“擊垮一家互聯網公司的最快方式不是運營瘋狂燒錢、不是產品經理胡亂決策,而是系統核心功能的持續不可用。”的確,我們常會見到一次大規模宕機導致企業損失上千萬,甚至市值大量蒸發。由此可見,系統穩定性和高可用的重要性。

在企業業務系統中,技術選型多種多樣,系統的性能和健壯性參差不齊,業務流量變化無常,如何才能保證各種業務流量安全運營,系統在任何情況下都不會崩潰呢?InfoQ 採訪了 QCon 全球軟件開發大會(北京站)2020 的講師朱龍雲,他和我們分享了關於系統負載保護的設計原則,以及發生流量突變時的具體應對措施。

負載保護的總體原則

雖然業務系統在正常情況通常是感知不到負載保護的存在,但是負載保護卻是所有系統都必須具備的能力,它可以防止系統“崩潰”。那麼,常見系統的負載保護在設計之初一般都遵循什麼樣的設計原則呢?

朱龍雲表示:雖然各個系統的負載保護設計都會有自身的特點,但從設計角度從下到上基本可分四層:

  • 通用層:這一層是系統通常都需要的基礎屬性。例如:易部署、高度可觀察,具備容災和擴縮容能力,隔離失敗 (服務 / 模塊)
  • 機制層:這一層包含了與負載保護密切相關的基礎屬性,在負載保護系統演化中相對策略層變化是慢的。例如低消耗、低耦合,容錯性、健壯性、適應性、伸縮性和異構性。
  • 策略層:這一層是負載保護的策略算法,是在系統外側最容易被看到的,容易引起廣泛的討論。我們常講到的限流、降級和熔斷算法就在這一層。
  • 系統層:這一層主要是根據負載保護運營反饋,找出系統整體設計的缺陷和不足,並進行相應調整,並將系統設計與自動擴容融合。

如果具體到負載策略的設計原則,一般需要考慮到調用鏈、業務與資源、整體與局部、擴展性等等。

  • 調用鏈:在這一維度,我們需要管控好上游入口的流量,實時計算自身服務資源消耗,並實時評估下游服務服務質量,確保整個調用鏈整體流量安全。
  • 業務與資源:通常,業務流量會有時間錯峯,我們可以將錯峯業務部署在一起,提高機器資源利用率。但這樣可能會導致業務之間相互影響,負載保護就在此時發揮作用,當業務負載超過自身預分配資源時,繼續使用系統尚未被其他業務消耗的資源。當各個業務總體消耗資源超過系統整個負載安全上限,按一定策略對相應業務進行限制;
  • 整體與局部:達到整體效果的負載保護需要“均勻”分配到各個最小計算單元,但這裏的“均勻”不是絕對數量的“均勻”,而是與每個計算單元相匹配的“均勻”,即與系統的負載均衡相匹配;
  • 擴展性:業務對負載保護會有擴展性的需求,例如按照業務重要程度、用戶分佈或者資源消耗等進行個性化限流以及降級服務。

整體系統和單個服務的負載如何平衡?

系統的負載保護既包括單個服務的負載保護,也包括整體系統的負載保護,前文我們也講到了整體與局部負載保護的設計原則的關鍵詞是“均勻”,如何實現“均勻”呢?

我們可以分兩個部分來討論:

第一部分是整體系統與調用 topo 中某個節點關係。我們需要先了解系統中的負載脆弱點以及原因。

負載脆弱點可能是技術引起的,例如動態語言實現服務,性能就會差一些;可能是資源引起的,例如部署的物理資源較少;可能是業務引起的,例如計算密集或者外部依賴的問題。然後,我們需要針對脆弱點做好流量管理,自身負載的實時監測,對脆弱點上游做好熔斷機制,並做好監測預警,防止該點引起系統整體雪崩。同時從長遠角度考慮,還要儘可能優化或者消除因設計引起的系統脆弱點。

第二部分是單點服務集羣與計算單元的關係。

集羣中各個計算單元需要負載均衡,而通常情況下,各個計算單元是異構的,這就需要匹配相應的計算資源能力。負載保護需要保證當系統過載時,負載依舊是均衡的,避免出現有的計算單元過載,有的計算單元還有資源剩餘。

總之,負載保護的策略具體實現都需落實到單個計算資源,同時各個計算資源的信息需要上報彙總起來做整體決策。

上游模塊與下游服務的負載保護

除了整體系統與單個服務,我們還常會遇到上游模塊與下游服務之間的負載保護。朱龍雲表示:“上下游之間的負載保護最重要的是做到相互信任不依賴,對方通知異常,能根據通知信息採取措施。對方不通知也能及時發現異常,採取措施,不會因爲自身原因造成系統雪崩。”

展開來講就是上游需要爲下游做好流量保護,但是下游不依賴這種保護。當上遊沒有保護好,系統流量過載,下游能觸發自身的負載保護,當上遊故障,流量突然下降,下游也能發現。如果下游服務異常,不能提供正常服務,下游需主動通知上游。如果沒有通知,上游也需要能自身發現異常,並採取措施。而當下遊服務正常時,上游也要及時探測到,並開放對外服務。

如何評判負載保護的效果

一個系統的負載保護設計好了之後,如何評估設計得是否合理呢?一般來說,我們會通過以下指標來判斷:

  • 低能耗:負載保護本身不能擠佔太多的系統資源;
  • 適應性:負載保護本身對流量變化不敏感,不會因爲業務流量變化而頻繁擴縮容;
  • 容災能力:負載保護的作用是幫助業務儘快恢復,所以自己不能成爲瓶頸,自身故障不能影響到整個業務系統;
  • 透明擴縮容:業務系統擴縮容時,應該感覺不到負載保護的存在;
  • 健壯性:保護機制觸發時機既不能過於敏感,造成系統顛簸,同時也不能遲鈍。

一個真實存在的系統往往都是有自身服務的職責和邊界,因此一個合格的負載保護系統也要協助系統在各種場景下對外提供服務。

  1. 在一定負載範圍內,系統在不觸發負載保護的情況下,對外提供高可用服務;
  2. 系統對外提供有損服務,這種場景已經觸發負載保護;
  3. 系統只保證自己正常運行,不再保證對外服務的數量,排除異常之後,系統可以立刻對外提供高可用服務,這種場景需要負載保護深度接入;
  4. 系統不對外服務,異常排除之後,結合線下處理,系統在可預測、可控時間範圍內恢復對外服務。

流量突變時,負載保護如何應對?

當流量發生突變,系統中的負載保護應該採取什麼樣的措施呢?

負載過高

當系統負載過高時,通常會採用三種措施來保護系統,限流、降級和熔斷。

限流一般是指限制入口流量,觸發機制可以是提前預設閾值、下游通知或者自發檢測到資源過載,而具體策略可以是剛性,也可以是彈性。一般來說,剛性是指超過一定量之後,就全部不再提供服務,而彈性就會涉及降級。

降級一般是指限制業務或用戶。如果是讀寫分離的業務,通常讀的量比較大,寫的量比較小,而且敏感,所以當系統過載時,就會限制讀的量,而寫的量不會直接限制。讀少了,同時會自動引起寫減少。這種方式即使是觸發了負載保護,也會使系統儘可能有好的體驗。限制用戶指的是按照一定策略使得部分用戶無法訪問該服務。

熔斷主要是發現自身或者下游不能正常服務,主動不再對上游提供服務。但是熔斷也可以引入降級服務策略,允許部分服務正常運行。

總體來看,限流偏向於管理入口流量,熔斷偏向於保護下游服務。降級是爲了在系統觸發負載保護時,儘可能提供彈性服務。一般來說,熔斷比限流嚴重,而限流比降級嚴重。

負載過低

與負載過高相比,大家對於負載過低的關注度會比較低,但其實負載過低有時也會帶來嚴重後果。

一般來說,出現負載過低的情況有以下幾種:

第一種是比較直接的,業務量太少,這種情況的解決方法就是與其它業務混合部署,再採用負載保護;

第二種是關鍵業務或節點進行了獨立部分,這種情況一般是企業根據業務情況做出的運營策略,不需要調整;

第三種是服務實現的缺陷,例如服務裏面存在 idle 操作,造成機器資源利用率不高;

第四種是服務設計的缺陷,例如 QPS 達到一定閾值,服務器性能就會斷崖式下降,造成機器資源利用率不高。

負載均衡

負載過高或過低都不可行,我們需要做到負載均衡。首先,調用鏈節點之間的負載要均衡,沒有明顯瓶頸,否則容易觸發負載保護;其次,單個服務集羣的各個服務器之間的負載要均衡,包括硬件和軟件的負載均衡。

如何實現負載均衡呢?朱龍雲認爲主要考慮以下幾個方面:

  1. 系統的冷啓動策略,可以從一個預設的平衡條件開始逐步調整;
  2. 系統性能指標,例如響應時間,錯誤碼等;
  3. 負載調度策略,基於機器的服務能力來分配,例如服務的平均響應時間、成功比例以及內部隊列長度等;
  4. 負載均衡的精度和穩定性,精度高的好處是能夠區分出異構機器的服務能力,而壞處在於頻繁調整各個機器服務權重,有可能引起系統顛簸;
  5. 負載均衡接入方式,常見的有網關接入和 Agent 接入;
  6. 即使觸發了負載保護依然需要負載均衡,不然就有可能造成系統服務能力浪費。

企業中的負載保護存在哪些問題?

在企業中,我們經常會遇到這三種負載保護的情況:第一種是企業在系統設計之初就考慮負載保護,系統上線之後沒有出現大故障,負載保護不斷優化、完善,並與業務邏輯進一步融合;第二種是在系統運營過程中遇到了負載保護的問題,並得到了比較好的解決;第三種是遇到了負載保護問題,不能徹底解決,負載保護系統部分可用,需要堆人力來運營系統。

第一種情況是最理想的,但是現實中很少見,因爲這其中不只涉及到技術問題,同時也需要考慮項目進度、成本等多種因素。而其它兩種情況都是企業實踐中比較常見,當系統平穩運營時,資源利用率的情況也比較好,一旦發生外部流量陡增或者是關鍵路徑觸發異常等情況,各個服務之間的連鎖反應可能會使整個系統崩潰,短時間內無法恢復,同時共享資源的業務也會受到影響。

在單體架構階段,負載保護會比較簡單,系統崩潰了也較容易恢復。而在微服務階場景下,負載保護就複雜了,由於調用關係複雜,系統因過載崩潰了,需要先找到引起奔潰的節點,有時可能是幾個節點連環觸發的,系統無法通過簡單擴容恢復。

所以,我們需要在系統設計之初就考慮到負載平衡,同時做好以下工作:

  • 檢查現有系統是否存在明顯短板,容易觸發過載;
  • 系統與外部系統之間要做好入口流量控制;
  • 系統內“玻璃體質”服務的模塊調用方要有錯誤抑制、熔斷、降級等機制;
  • 關鍵服務的負載要實時監測、評估,並適當提高冗餘資源;
  • 負載保護要與監控緊密結合,儘早發現系統異常,及時觸發自動擴容;
  • 負載保護觸發時要採訪業務側提供的策略;
  • 根據系統運營結果,及時發現系統在設計和運營方面的不足。

在流量管理方面,業界還出現了一個新的“風向標”——Istio,其理念是將業務中的很多微服務治理功能下沉到基礎設施。這個設計理念是相當有創造力的,其實從軟件架構設計的角度來看,這些思想方法並不獨特,我們或多或少都曾應用過,例如集羣入口流量管理與 Istio 南北向通信,集羣內彈性熔斷與 Istio 東西向通信,集羣內脆弱服務的保護與 Istio 的智能代理,流控實現中數據和控制分離與 Istio 中數據平面和控制平面分離。但需要注意的是,再安全健壯的基礎設施也擋不住業務“自殺式”設計,業務只有科學合理設計,才能與基礎設施相得益彰,一起發揮整體效能。

嘉賓介紹

朱龍雲,騰訊科技增值服務部互娛 AMS 監控系統負責人。2007 年加入騰訊,曾負責騰訊網網站廣告發布系統,從事 CPD/CPC/CPM 等形式廣告發布和運營,在廣告 / 監控 / 流控等領域擁有多項專利。現就職於騰訊遊戲增值服務部,曾參與開發過 Pandora 手遊營銷系統,支持手遊時代新營銷形式;主持設計和實現 AMS 系統全局負載保護系統,保證微服務系統在流量突變時安全運。當前主要負責 AMS 遊戲營銷監控系統,從事現網故障分析、弱閾值設置監控、主動探測系統和異常檢測等方面工作。對分佈式計算,大數據和函數式編程等領域比較感興趣。

QCon北京2020的演講中,你將從朱龍雲老師的分享中瞭解到:微服務環境上游流控/本機負載保護/下游熔斷方案相結合的整體系統負載保護方案;微服務環境下監控設計的方案,與傳統監控差異,以及未來可能的發展方向。點擊瞭解詳情

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章