熔斷 Circuit Breaker Pattern

在實際環境中,當下遊服務或者存儲出現錯誤,而且需要大量時間來恢復時,服務如何正確處理這些錯誤決定了服務本身的健壯性和穩定性,而熔斷模式則是解決方法之一。

背景

在分佈式系統中,一個服務會與多個下游服務打交道,當它訪問下游時,很可能因爲網絡問題(連接過慢、連接超時)、下游服務負載過高或者暫時不可用,導致訪問失敗。這些問題通常持續時間很多,所以服務爲了保證自己對外接口的穩定性,一般會採取一些錯誤處理措施,例如 重試 。
然而,如果下游服務出現比較嚴重的問題,需要較長的時間進行恢復,這種情況下重試是不能解決問題的,反而可能會妨礙問題的恢復,甚至帶來"雪崩"效應。

解決方案

熔斷可以讓服務在執行某個操作出現大量失敗時,不再繼續嘗試執行操作。同時熔斷可以讓服務去檢測操作是否恢復正常,如果恢復正常,再去正常執行操作。
注意,熔斷和重試不同,重試 讓服務在執行操作失敗後,再次執行,直到執行成功(每次重試時間間隔不一樣,詳細可以參考 重試 Retry Pattern)。
針對那些可能會失敗的操作,熔斷器會提供一個Proxy,介於服務和執行操作之間。這個Proxy會檢測服務執行操作失敗的比例,然後決定是否繼續讓服務執行操作,還是直接返回操作執行失敗。
爲了滿足熔斷器最基本的功能,Proxy會實現一個狀態機,擁有下面一些狀態,

  • Closed。在Closed狀態下,針對服務的請求,Proxy會去實際執行操作。熔斷器會記錄最近一段時間操作失敗的次數,每次操作執行失敗都會加一。如果失敗次數超過了一個給定的閾值,熔斷器會切換到Open狀態。在Open狀態下,Proxy會開啓一個定時器,到了指定的時間後,熔斷器會進入到Half-Open狀態。注:設置定時器的目的是給出現問題的下游一些時間進行恢復,在這段時間內不再訪問下游,避免問題加劇。
  • Open。在Open狀態下,針對服務的請求,Proxy直接返回失敗,而不是執行操作。
  • Half-Open。在Half-Open狀態下,一小部分請求會被放過,去執行實際的操作(其餘的還是直接拒絕,返回執行失敗)。如果被放過的請求全部執行成功,Proxy會認爲下游已經從錯誤狀態中恢復,熔斷器會切換到Closed狀態(同時清空之前累積的錯誤信息)。如果任何一個請求執行失敗,熔斷器依舊會認爲下游不可用,切換到Open狀態,同時再次開啓一個定時器。Half-Open是一個過渡狀態,避免由於狀態切換,服務向下遊發送過多請求,加劇下游服務的問題恢復。
    熔斷器狀態轉換
    上圖展示了熔斷器三個狀態之間的切換。需要注意的是,Closed狀態下,熔斷器的錯誤計數是基於時間進行統計的,每隔一段時間計數就會重置,這樣可以避免少許錯誤(例如下游的輕微抖動)導致熔斷器進入Open狀態。也就是說錯誤計數是基於時間桶的,只有當某個時間桶累積的錯誤數達到閾值,熔斷器纔會切換到Open狀態。

個人看法

熔斷器的應用其實可以很廣,

  • 服務訪問下游存儲、訪問其他服務等。熔斷可以避免造成服務雪崩
  • 服務本身的處理邏輯。例如優惠券發放等業務邏輯,如果由於系統漏洞或者惡意攻擊導致大量發放大額優惠券,熔斷器及時開啓可以避免大量損失

實現

todo 熔斷器的實現待補充

參考文章:

  • https://docs.microsoft.com/en-us/previous-versions/msp-n-p/dn589784(v=pandp.10)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章