天天看點

自适應熔斷限流揭秘

作者:閃念基因

前言

自适應熔斷與限流是在分布式系統中常用的機制,用于保護系統免受服務雪崩效應與突發流量影響。它能夠根據系統的負載情況和性能名額自動調整限流政策,以確定系統能提供穩定可靠的服務,目前在業内已經有了不少的探索與實踐。

熔斷限流使用場景

限流

限流主要的應用場景為應對流量激增的場景(如活動促銷,外部流量攻擊等)。如下圖,當系統流量激增時,如不加以限制,可能會導緻系統負載被打滿,緻使服務崩潰,最終導緻服務不可用。

自适應熔斷限流揭秘

通過限流,僅允許部分流量的請求可以通過,其餘請求會直接快速失敗,即便突發流量出現時,服務始終僅承載部分請求,系統負載可控,保證了服務能穩定可用。

自适應熔斷限流揭秘

熔斷

熔斷主要的應用場景為依賴的服務出現故障時防止出現服務雪崩(如下遊逾時,db故障等)。如下圖,當下遊服務故障導緻逾時,由于長時間不響應會導緻上遊服務請求産生阻塞,導緻系統資源增加(常見的如tomcat線程池、連接配接池等),如持續故障,則請求阻塞會持續增加導緻上遊系統線程池資源耗盡,導緻上遊服務不可用,并且會向上産生級聯故障,最終因底層服務的故障導緻整個鍊路的服務雪崩。

自适應熔斷限流揭秘

通過熔斷可以在下遊發生故障之後,針對下遊的調用進行快速失敗,這樣就避免了系統資源因下遊故障而耗盡,使系統保持可用,同時熔斷後也會定期進行下遊探測,當下遊恢複後,會退出熔斷,自動恢複下遊調用。

自适應熔斷限流揭秘

傳統熔斷限流存在的問題

傳統熔斷限流主要是用戶端模式如hystrix, sentinel靜态流控功能,存在着一些弊端:

  1. 配置滞後,人工評估易存在疏漏;通常都是系統出現故障後,才進行介入,實際可能已經對業務産生了不好的影響。
  2. 門檻值難以設定,配置成本高;通常門檻值的确定需要結合生産壓測的實施才能準确設定,但實際在生産進行壓測的成本很高,并且規則中變量衆多,有一定的上手門檻。
  3. 門檻值設定存在過時的問題;由于系統是在不斷的疊代中的,是以門檻值也可能随着版本的疊代而逐漸不适用,進而使系統失去了保護。
  4. 跨語言支援不佳;已有的元件僅對java生态支援較好,但對于python,go等語言生态的支援有限。

信也自适應熔斷限流的優勢

  1. 可作為兜底政策;自适應政策有較高的啟發值,是以可作為兜底政策提前配置開啟。
  2. 使用門檻低;采用的是自适應的政策,無複雜的配置項,不需要進行壓測,僅需選擇開啟與關閉即可,且政策主要根據系統的負載情況進行決策,随着版本疊代,也不會失效。
  3. 0成本接入,支援跨語言;采用mesh的方式實作,具體的限流與熔斷介入是在邊車上進行的,是以應用無需用戶端接入,能應用在各種語言生态的系統上。

自适應熔斷限流政策

自适應限流

  • 政策核心邏輯:資源水位線自适應,通過目前CPU與目标值的誤差調整QPS,使CPU趨近于目标值。
  • 核心算法:PID算法
  • 業内實踐:淘寶noah、螞蟻mosn等
  • 算法概述:PID算法利用回報來檢測偏差信号,并通過偏差信号來控制被控量。而控制器本身就是比例、積分、微分三個環節的加和。使用廣泛,在四軸飛行器,平衡小車、汽車定速巡航、溫度控制器等場景均有應用。算法明細見下圖,其中Kp:比例增益,用于控制調節幅度;Ki:積分時間常數,用于補償誤差;Kd:微分時間常數,用于抑制波動;e(t):cpu與基準線的誤差;u(t):調整的qps;其中基準線取的是80%。
自适應熔斷限流揭秘

自适應熔斷

  • 政策核心邏輯:通過計算實際被下遊拒絕的機率來控制請求是否熔斷
  • 核心算法:SRE算法
  • 業内實踐:B站kratos、go-zero、小米、QQ音樂微服務等
  • 算法概述:SRE算法是Google提出的一種彈性熔斷算法,稱之為Handing Overload,不同于傳統熔斷算法,SRE算法沒有半開的狀态,也沒有完全開啟的狀态,通過計算下遊服務的拒絕率來控制流量的發送,在保護自身不被下遊拖垮的同時,盡可能釋放請求到下遊,最大化保證業務的完整性。算法明細見下圖,其中requests: 一個時間視窗的請求總量;Accepts: 成功請求數量;K: 倍率,K 越小表示越激進,越小表示越容易被丢棄請求,K建議區間[1.5, 2]。
自适應熔斷限流揭秘

自适應熔斷限流整體方案

  • 名額采集與轉儲;首先利用otel進行熔斷限流名額的采集,采集過程中otel會定期通過自适應熔斷限流平台進行節點發現,隻有開啟了熔斷限流功能的執行個體才會進行名額采集。采集到名額會批量推送至kafka中,由資料轉儲子產品進行名額消息消費,并針對監控資料進行預處理後存入redis中。
  • 自适應計算引擎;根據開啟的規則進行自适應熔斷限流觸發的掃描,根據預設的熔斷限流自适應政策從redis中擷取對應的監控名額進行熔斷限流觸發判定,判斷規則中也針對誤觸發做了許多的條件限制,比如會過濾掉非流量導緻的負載升高場景等。針對觸發的規則會生成自适應調節記錄,并下發熔點限流指令,同時會周期性的進行自适應政策計算更新熔斷限流的門檻值,直至滿足恢複的條件,滿足恢複條件後會下發熔斷限流恢複指令進行恢複,觸發與恢複都會通過谛聽監控平台進行告警通知。
  • 規則轉換:規則轉換子產品會監聽下發熔斷限流指令來建構EnvoyFilter CRD,将熔斷限流指令轉換成邊車測的流控規則,熔斷限流指令轉換為EnvoyFilter後會通過mesh的控制面IstioD采用XDS協定下發給邊車。
  • 邊車:根據下發的流控XDS配置執行入口(限流)或出口(熔斷)的流控。

問題與優化

1、XDS下發性能問題

添加EnvoyFilter後觸發同namespace下所有Pod的xDS推送,在自适應調節過程會頻繁變更EnvoyFilter導緻推送頻率過高,mesh控制面Istio的負載也會大幅上升,是以針對Istio的源碼進行了性能優化,在推送XDS時進行label比對,僅會對label比對的執行個體推送XDS配置。

自适應熔斷限流揭秘

2、自适應熔斷在envoy上實作問題

由于在envoy上實作自适應熔斷并無開源經驗可借鑒,SRE熔斷算法需要類似與基于機率的方式限流,envoy原生并沒有機率限流的政策。經過研究與測試,采用超長token投遞頻率結合限流生效比例的方式模拟出機率限流的效果,經多次壓測驗證,誤差穩定在2%範圍内,滿足實際熔斷要求。

自适應熔斷限流揭秘

3、API監控名額次元爆炸問題

由于自适應熔斷場景對熔斷目标的粒度要求高,需要是API次元,由于熔斷場景主要針對的是出口調用的場景,且熔斷發生時下遊并未傳回封包,是以無法使用spring ServletRequest.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE)來擷取接口路徑,這種情況下當路徑中存在變量時,會出現次元爆炸的問題。是以通過研發模闆比對EnvoyFilter,當接口開啟熔斷功能時會下發模闆比對EnvoyFilter,當向下遊發起調用時會先通過模闆比對EnvoyFilter進行接口比對,自适應熔斷僅會作用在模闆比對通過的接口請求。

自适應熔斷限流揭秘

此外還做了許多的難點攻克與優化,如算法調優、istio監控名額定制、 envoy精細化限流失準問題和api server性能問題等

自适應熔斷限流平台

自适應熔斷限流設定

自适應限流設定沒有複雜的規則參數設定,僅需選擇功能開關的開啟或關閉,并且支援執行個體級别的灰階。

自适應熔斷限流揭秘

自适應熔斷設定支援API次元與站點次元,API與站點清單是根據監控資訊自動提取的,且無額外規則參數設定,使用者僅需關注開關的開啟與關閉。

自适應熔斷限流詳情與快照

自适應熔斷限流揭秘

自适應限流記錄詳情中除了包含觸發的基礎的站點執行個體資訊外還包含了觸發恢複的原因、條件描述,及觸發與恢複前後的監控名額快照,通過快照可以友善的進行問題排查與分析。如圖上所示,當流量導緻CPU飙升後,自适應限流會介入,使CPU負載降低直至趨近于設定的目标水位線,進而保障了服務的可用性。同時由于部分請求快速失敗了,導緻整體吞吐量實的提升。

自适應熔斷限流揭秘

自适應熔斷記錄詳情與自适應限流詳情類似,也是由基礎資訊與監控名額快照組成,通過快照可以發現當下遊出現大量逾時後,自适應熔斷開始介入,大部分請求被快速失敗,避免了服務被下遊拖垮。

但與傳統熔斷不同的是,自适應熔斷始終盡可能的往下遊釋放請求,當下遊逾時有所恢複時,流量也能快速實作恢複,在保證自身服務不被下遊拖垮的同時,最大化的保證了業務的完整性。

最後

目前我們已經完成了自适應限流與熔斷的階段性落地,完成了部分站點的試點與開啟,後續也會進一步的探索,如自适應限流細化到接口層面,僅針對導緻負載上升的接口進行自适應限流;進一步細化名額粒度,提升自适應政策觸發與恢複的靈敏度等;使服務保障機制向更精準、更高效、更穩定的方向發展。

作者介紹

Chasen,現任基礎架構研發專家

來源-微信公衆号:拍碼場

出處:https://mp.weixin.qq.com/s/m9ujAciRoIrs5GmiYSX-TQ