一般在微服架構中,有一個元件角色叫熔斷器。顧名思義,熔斷器起的作用就是在特定的場景下關掉目前的通路,進而起到保護整個系統的效果。
在微服務架構中,一般我們的獨立服務是比較多的,每個獨立服務之間劃分責任邊界,并通過約定協定接口來進行通信。當我們的調用鍊路複雜依賴多時,很可能會發生雪崩效應。
假設有這麼一個場景,有A, B, C, D四個獨立服務,A會依賴B,C,D;當D發生負載過高或網絡異常等導緻響應過慢或逾時時,很可能A會是以堆積過多的等待連結,進而導緻A的狀态也轉為異常,後面依賴到A的其他服務跟着發生鍊式反應,這将會導緻大面積的服務不可用,即使本來是一些沒有依賴到B,C,D的服務。如下圖所示:

這不是我們希望看到的結果,是以這個時候熔斷器可以派上用場。最簡單的做法,我們為每個依賴服務配置一個熔斷器開關,正常情況下是關閉的,也就是可以正常發起請求;當請求失敗(逾時或者其他異常)次數超過預設值時,熔斷器自動打開,這時所有經過這個熔斷器的請求都會直接傳回失敗,并沒有真正到達所依賴的服務上。這時服務A本身仍然是能正常服務的, 如下圖所示:
那麼熔斷器具體又是怎麼工作的呢?來看下,一個擁有基本功能的熔斷器的狀态機大體是這樣子的:
主要在三種狀态中轉換:
關閉狀态 :
當熔斷器處于關閉狀态時,請求是可以被放行的;
當熔斷器統計的失敗次數觸發開關時,轉為打開狀态。
打開狀态 :
當熔斷器處于打開狀态時,所有請求都是不被放行的,直接傳回失敗;
隻有在經過一個設定的時間視窗周期後,熔斷器才會轉換到半開狀态
半開狀态 :
當熔斷器處于半開狀态時,目前隻能有一個請求被放行;
這個被放行的請求獲得遠端服務的響應後,假如是成功的,熔斷器轉換為關閉狀态,否則轉換到打開狀态。
最後,基于這個狀态機,用Golang實作了一個隻包含最基本功能的熔斷器:github.com/moxiaomomo/circuitbreaker, 有興趣可以參考一下,也歡迎指正。
主要用法如下:
// 建立一個熔斷器執行個體,指定熔斷時間視窗和失敗觸發開關門檻值等
cbs := NewCirucuitBreaker(time.Second, 150, 20)
// 向熔斷器注冊command(可以了解為對應的服務請求id)
testcmd := "call_serviceB"
suc := cbs.RegisterCommandAsDefault(testcmd)
// 向熔斷器報告目前command的執行結果(成功或失敗)
cbs.Report(testcmd, false)
cbs.Report(testcmd, true)
// ...
// 向熔斷器詢問目前該command是否能被執行
execAllow := cbs.AllowExec(testcmd)
---------------------
作者:moxiaomomo
來源:CSDN
原文:https://blog.csdn.net/moxiaomomo/article/details/80776906
版權聲明:本文為部落客原創文章,轉載請附上博文連結!