天天看點

熔斷降級設計理念 系統次元的自适應保護能力

Sentinel 介紹

随着微服務的流行,服務和服務之間的穩定性變得越來越重要。Sentinel 是面向分布式服務架構的流量控制元件,主要以流量為切入點,從流量控制、熔斷降級、系統自适應保護等多個次元來幫助您保障微服務的穩定性。

熔斷降級

什麼是熔斷降級

除了流量控制以外,降低調用鍊路中的不穩定資源也是 Sentinel 的使命之一。由于調用關系的複雜性,如果調用鍊路中的某個資源出現了不穩定,最終會導緻請求發生堆積。這個問題和 ​​Hystrix​​ 裡面描述的問題是一樣的。

Sentinel 和 Hystrix 的原則是一緻的: 當調用鍊路中某個資源出現不穩定,例如,表現為 timeout,異常比例升高的時候,則對這個資源的調用進行限制,并讓請求快速失敗,避免影響到其它的資源,最終産生雪崩的效果。

熔斷降級設計理念

在限制的手段上,Sentinel 和 Hystrix 采取了完全不一樣的方法。

Hystrix 通過​​線程池​​的方式,來對依賴(在我們的概念中對應資源)進行了隔離。這樣做的好處是資源和資源之間做到了最徹底的隔離。缺點是除了增加了線程切換的成本,還需要預先給各個資源做線程池大小的配置設定。

Sentinel 對這個問題采取了兩種手段:

  • 通過并發線程數進行限制

和資源池隔離的方法不同,Sentinel 通過限制資源并發線程的數量,來減少不穩定資源對其它資源的影響。這樣不但沒有線程切換的損耗,也不需要您預先配置設定線程池的大小。當某個資源出現不穩定的情況下,例如響應時間變長,對資源的直接影響就是會造成線程數的逐漸堆積。當線程數在特定資源上堆積到一定的數量之後,對該資源的新請求就會被拒絕。堆積的線程完成任務後才開始繼續接收請求。

  • 通過響應時間對資源進行降級

除了對并發線程數進行控制以外,Sentinel 還可以通過響應時間來快速降級不穩定的資源。當依賴的資源出現響應時間過長後,所有對該資源的通路都會被直接拒絕,直到過了指定的時間視窗之後才重新恢複。

系統負載保護

Sentinel 同時提供​​系統次元的自适應保護能力​​。防止雪崩,是系統防護中重要的一環。當系統負載較高的時候,如果還持續讓請求進入,可能會導緻系統崩潰,無法響應。在叢集環境下,網絡負載均衡會把本應這台機器承載的流量轉發到其它的機器上去。如果這個時候其它的機器也處在一個邊緣狀态的時候,這個增加的流量就會導緻這台機器也崩潰,最後導緻整個叢集不可用。

針對這個情況,Sentinel 提供了對應的保護機制,讓系統的入口流量和系統的負載達到一個平衡,保證系統在能力範圍之内處理最多的請求。

 system-adaptive-protection https://sentinelguard.io/zh-cn/docs/system-adaptive-protection.html

系統自适應保護

Sentinel 系統自适應保護從整體次元對應用入口流量進行控制,結合應用的 Load、總體平均 RT、入口 QPS 和線程數等幾個次元的監控名額,讓系統的入口流量和系統的負載達到一個平衡,讓系統盡可能跑在最大吞吐量的同時保證系統整體的穩定性。

背景

在開始之前,先回顧一下 Sentinel 做系統自适應保護的目的:

  • 保證系統不被拖垮
  • 在系統穩定的前提下,保持系統的吞吐量

長期以來,系統自适應保護的思路是根據硬名額,即系統的負載 (load1) 來做系統過載保護。當系統負載高于某個門檻值,就禁止或者減少流量的進入;當 load 開始好轉,則恢複流量的進入。這個思路給我們帶來了不可避免的兩個問題:

  • load 是一個“果”,如果根據 load 的情況來調節流量的通過率,那麼就始終有延遲性。也就意味着通過率的任何調整,都會過一段時間才能看到效果。目前通過率是使 load 惡化的一個動作,那麼也至少要過 1 秒之後才能觀測到;同理,如果目前通過率調整是讓 load 好轉的一個動作,也需要 1 秒之後才能繼續調整,這樣就浪費了系統的處理能力。是以我們看到的曲線,總是會有抖動。
  • 恢複慢。想象一下這樣的一個場景(真實),出現了這樣一個問題,下遊應用不可靠,導緻應用 RT 很高,進而 load 到了一個很高的點。過了一段時間之後下遊應用恢複了,應用 RT 也相應減少。這個時候,其實應該大幅度增大流量的通過率;但是由于這個時候 load 仍然很高,通過率的恢複仍然不高。

​​TCP BBR​​ 的思想給了我們一個很大的啟發。我們應該根據系統能夠處理的請求,和允許進來的請求,來做平衡,而不是根據一個間接的名額(系統 load)來做限流。最終我們追求的目标是 在系統不被拖垮的情況下,提高系統的吞吐率,而不是 load 一定要到低于某個門檻值。如果我們還是按照固有的思維,超過特定的 load 就禁止流量進入,系統 load 恢複就放開流量,這樣做的結果是無論我們怎麼調參數,調比例,都是按照果來調節因,都無法取得良好的效果。

Sentinel 在系統自适應保護的做法是,用 load1 作為啟動控制流量的值,而允許通過的流量由處理請求的能力,即請求的響應時間以及目前系統正在處理的請求速率來決定。

系統規則

系統保護規則是從應用級别的入口流量進行控制,從單台機器的總體 Load、RT、入口 QPS 和線程數四個次元監控應用資料,讓系統盡可能跑在最大吞吐量的同時保證系統整體的穩定性。

系統保護規則是應用整體次元的,而不是資源次元的,并且僅對入口流量生效。入口流量指的是進入應用的流量(​

​EntryType.IN​

​),比如 Web 服務或 Dubbo 服務端接收的請求,都屬于入口流量。

系統規則支援以下的門檻值類型:

  • Load(僅對 Linux/Unix-like 機器生效):當系統 load1 超過門檻值,且系統目前的并發線程數超過系統容量時才會觸發系統保護。系統容量由系統的 ​

    ​maxQps * minRt​

    ​ 計算得出。設定參考值一般是 ​

    ​CPU cores * 2.5​

    ​。
  • CPU usage(1.5.0+ 版本):當系統 CPU 使用率超過門檻值即觸發系統保護(取值範圍 0.0-1.0)。
  • RT:當單台機器上所有入口流量的平均 RT 達到門檻值即觸發系統保護,機關是毫秒。
  • 線程數:當單台機器上所有入口流量的并發線程數達到門檻值即觸發系統保護。
  • 入口 QPS:當單台機器上所有入口流量的 QPS 達到門檻值即觸發系統保護。