故事要從我讀大學(xué)那會說起。
因為功率問題,很多寢室都是不讓用吹風(fēng)筒和熱水壺的。
但我那時候頭鐵,不僅用,而且還同時開了兩個熱水壺和一個吹風(fēng)筒。直接給寢室電路來了個壓" />

微服務(wù)領(lǐng)域里有個詞叫服務(wù)熔斷,你知道這是啥不?
故事要從我讀大學(xué)那會說起。
因為功率問題,很多寢室都是不讓用吹風(fēng)筒和熱水壺的。
但我那時候頭鐵,不僅用,而且還同時開了兩個熱水壺和一個吹風(fēng)筒。直接給寢室電路來了個壓測。
不出意外的出了意外,寢室直接停電。
一時間,隔壁寢室燈火通明,我們寢室一片漆黑。
作為本科專業(yè)電氣工程的靚仔,我們意識到,這妥妥是電路過載導(dǎo)致斷路器跳閘了。
于是我們趁社管阿姨不注意,偷偷摸進(jìn)配電房,手動將斷路器開關(guān)復(fù)位,寢室就來電了。
是真的有驚無險。
如果沒有這個斷路器,寢室總電路怕是得因為過載全部燒掉,我們幾個妥妥會提前進(jìn)入社會大學(xué)。
我能畢業(yè),全靠這個斷路器!
看到這里,我們知道了斷路器的作用,就是在電路出問題的時候及時斷開電路,避免過載,從而保護(hù)電路。
在微服務(wù)領(lǐng)域,我們也可以借鑒斷路器的思路,引入了服務(wù)熔斷的概念。
服務(wù)熔斷,也就是 Circuit Breaker,本質(zhì)上是一種軟件設(shè)計模式,用于在分布式系統(tǒng)中處理服務(wù)調(diào)用失敗的情況。
假設(shè)有個 A 服務(wù)調(diào)用 B 服務(wù)的場景,如果 B 服務(wù)已經(jīng)出現(xiàn)頻繁失敗的情況,A 繼續(xù)調(diào)用只會加劇 B 服務(wù)的負(fù)擔(dān),嚴(yán)重的時候,有可能導(dǎo)致 B 服務(wù)崩潰,甚至出現(xiàn) B 服務(wù)重啟后立馬被打崩的情況。因此,最好的做法是,在一段時間內(nèi)先不要再頻繁調(diào)用 B 服務(wù)。
為了實現(xiàn)這個保護(hù)效果,我們可以在 A 和 B 之間加一個熔斷器。當(dāng) B 服務(wù)頻繁失敗時,熔斷器可以防止 A 繼續(xù)頻繁調(diào)用 B 服務(wù),相當(dāng)于阻斷服務(wù)間的請求,并且還能在 B 服務(wù)恢復(fù)正常之后,恢復(fù) A 對 B 的調(diào)用。

熔斷器的作用
工作原理也和上文提到的宿舍電路里的斷路器類似。當(dāng)服務(wù)調(diào)用失敗的次數(shù)超過某個閾值時,熔斷器會自動“打開”(Open),阻止進(jìn)一步的服務(wù)調(diào)用,防止不斷報錯重試導(dǎo)致壓垮被調(diào)用服務(wù)。
然后在在一段時間之后,熔斷器開始嘗試允許少量的請求通過,以檢查服務(wù)是否已經(jīng)恢復(fù),也就是所謂的“半打開”(HalfOpen)。
如果這些請求成功,熔斷器會“關(guān)閉”(Close),系統(tǒng)恢復(fù)正常的服務(wù)調(diào)用;但如果調(diào)用還是失敗,那熔斷器會繼續(xù)再次回到“打開”(Open)狀態(tài)。
上面提到的三個狀態(tài)Open,HalfOpen和Close是服務(wù)熔斷中非常重要的三個狀態(tài)。

熔斷器關(guān)閉

熔斷器半打開

熔斷器打開
它們的狀態(tài)流轉(zhuǎn)關(guān)系就像下圖這樣。

熔斷狀態(tài)機(jī)
可以看出,熔斷器的邏輯其實很簡單,而且這么通用的功能,必然有現(xiàn)成的庫可以直接拿來用。
比如阿里開源的sentinel-golang。
使用也比較簡單。只需要三步。
"github.com/alibaba/sentinel-golang/core/circuitbreaker"通過circuitbreaker.LoadRules加載對應(yīng)的熔斷規(guī)則。
_, err = circuitbreaker.LoadRules([]*circuitbreaker.Rule{ // Statistic time span=5s, recoveryTimeout=3s, maxErrorRatio=40% { Resource: "api_url", Strategy: circuitbreaker.ErrorRatio, RetryTimeoutMs: 3000, MinRequestAmount: 10, StatIntervalMs: 5000, StatSlidingWindowBucketCount: 10, Threshold: 0.4, }, })這里面有幾個需要注意的地方:
在需要進(jìn)行熔斷保護(hù)的地方,加入下面的代碼:
e, b := sentinel.Entry("api_url") if b == nil { // 通過檢測,不需要熔斷,直接執(zhí)行api調(diào)用 err := api_call() if err != nil { sentinel.TraceError(e, err) } // 保證執(zhí)行完之后退出資源 e.Exit() }上面的 sentinel.Entry()方法內(nèi)部會自動檢測"api_url"這個資源是否需要打開熔斷器,如果 api 調(diào)用報錯了,可以通過 sentinel.TraceError 記錄下來,sentinel 內(nèi)部會根據(jù)報錯去計算報錯率,自動判斷要不要熔斷。
到這里,就算使用上熔斷器的能力啦。
本文鏈接:http://m.www897cc.com/showinfo-26-77684-0.html服務(wù)熔斷是指什么?你知道嗎?
聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。郵件:2376512515@qq.com
上一篇: GaussDB WDR分析之集群報告篇
下一篇: 歷史上那些臭名昭著的編程錯誤