熔斷器原理


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

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

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM