天天看點

微服務中的熔斷機制

一般在微服架構中,有一個元件角色叫熔斷器。顧名思義,熔斷器起的作用就是在特定的場景下關掉目前的通路,進而起到保護整個系統的效果。

在微服務架構中,一般我們的獨立服務是比較多的,每個獨立服務之間劃分責任邊界,并通過約定協定接口來進行通信。當我們的調用鍊路複雜依賴多時,很可能會發生雪崩效應。

假設有這麼一個場景,有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 

版權聲明:本文為部落客原創文章,轉載請附上博文連結!

繼續閱讀