聊聊Sentinel的熔斷降級(jí)
Sentinel的熔斷降級(jí)實(shí)現(xiàn)有兩個(gè)模式,一開(kāi)始是基于熔斷規(guī)則的簡(jiǎn)單處理(說(shuō)簡(jiǎn)單其實(shí)不簡(jiǎn)單),目前已改為了基于斷路器模式實(shí)現(xiàn),這也是業(yè)內(nèi)常見(jiàn)實(shí)現(xiàn)。
斷路器模式
斷路器模式中討論了 3 個(gè)主要狀態(tài)。他們是:
CLOSED
OPEN
HALF OPEN
讓我們簡(jiǎn)要了解一下?tīng)顟B(tài)……
CLOSED State
當(dāng)正在交互的兩個(gè)服務(wù)都啟動(dòng)并運(yùn)行時(shí),斷路器默認(rèn)關(guān)閉。斷路器會(huì)持續(xù)統(tǒng)計(jì)遠(yuǎn)程 API 調(diào)用的次數(shù)。
OPEN State
一旦遠(yuǎn)程 API 調(diào)用失敗百分比超過(guò)給定閾值,斷路器就會(huì)將其狀態(tài)更改為 OPEN 狀態(tài)。調(diào)用微服務(wù)會(huì)立即失敗,返回異常。也就是說(shuō),流量中斷了。
HALF OPEN State
在 OPEN 狀態(tài)停留給定的超時(shí)時(shí)間后,斷路器自動(dòng)將其狀態(tài)變?yōu)?HALF OPEN 狀態(tài)。在這種狀態(tài)下,只允許有限數(shù)量的遠(yuǎn)程 API 調(diào)用通過(guò)。如果失敗調(diào)用計(jì)數(shù)大于此有限數(shù)量,則斷路器再次變?yōu)?OPEN 狀態(tài),流量繼續(xù)中斷。否則關(guān)閉斷路器,流量恢復(fù)正常。
流程圖可描述如下:

實(shí)現(xiàn)
最經(jīng)典的實(shí)現(xiàn)就是Hytrix,而且它的實(shí)現(xiàn)是基于響應(yīng)式編程來(lái)做的;其次Spring官方出品的Resilience4j、Sentinel也是基于此方式實(shí)現(xiàn)。
Sentinel熔斷降級(jí)實(shí)現(xiàn)關(guān)鍵對(duì)象
我個(gè)人對(duì)Sentinel比較推崇,功能強(qiáng)大,源碼易讀,而且設(shè)計(jì)架構(gòu)簡(jiǎn)介。Sentinel框架中有三個(gè)關(guān)鍵的對(duì)象是一直貫徹整個(gè)框架的,也是最關(guān)鍵的三個(gè)個(gè)點(diǎn):ProcessorSlot、Rule(規(guī)則)與指標(biāo)數(shù)據(jù)統(tǒng)計(jì)(Bucket)。
ProcessorSlot
這里不多講,實(shí)現(xiàn)了責(zé)任鏈模式,基于SPI機(jī)制支持可擴(kuò)展性,這個(gè)設(shè)計(jì)很好,值得借鑒。其實(shí)也類似MVC框架的管道模式。DegradeSlot插槽實(shí)現(xiàn)斷路器模式,最終達(dá)到限流降級(jí)的目的。
規(guī)則與指標(biāo)數(shù)據(jù)統(tǒng)計(jì)
對(duì)于熔斷降級(jí)或是限流等場(chǎng)景,最后的實(shí)現(xiàn)結(jié)果一定是由于當(dāng)前的流量或是異常等維度指標(biāo)超出了限定值,這個(gè)過(guò)程就是規(guī)則(Rule)的體現(xiàn),而規(guī)則背后的開(kāi)關(guān)實(shí)現(xiàn)就是指標(biāo)數(shù)據(jù)的統(tǒng)計(jì)。這是我個(gè)人的理解,大白話表述。
指標(biāo)數(shù)據(jù)統(tǒng)計(jì)在Sentinel中對(duì)應(yīng)著三個(gè)抽象;暫時(shí)先不表述。如果要我來(lái)實(shí)現(xiàn)的話,我的思考是,有一個(gè)數(shù)據(jù)結(jié)構(gòu)存儲(chǔ)著在某個(gè)時(shí)間段內(nèi),統(tǒng)計(jì)了某些維度的數(shù)據(jù)(比如成功、異常、總計(jì)),而且這個(gè)數(shù)據(jù)結(jié)構(gòu)是隨著時(shí)間的推移不斷地統(tǒng)計(jì);現(xiàn)在給定一個(gè)時(shí)間點(diǎn)或是時(shí)間段,判斷是否需要限流或是熔斷;在這里就需要注意兩個(gè)問(wèn)題點(diǎn):
給定的時(shí)間是否在統(tǒng)計(jì)的時(shí)間范圍內(nèi)
在統(tǒng)計(jì)的時(shí)間范圍內(nèi),如果定位到對(duì)應(yīng)的數(shù)據(jù)結(jié)構(gòu)
指標(biāo)統(tǒng)計(jì)抽象
Sentinel是基于滑動(dòng)窗口實(shí)現(xiàn)資源的實(shí)時(shí)指標(biāo)數(shù)據(jù)統(tǒng)計(jì)的。
Sentinel使用Bucket統(tǒng)計(jì)一段時(shí)間內(nèi)的各項(xiàng)指標(biāo)數(shù)據(jù),這些指標(biāo)數(shù)據(jù)包括請(qǐng)求總數(shù)、成功總數(shù)、異??倲?shù)、總耗時(shí)、最小耗時(shí)等。一個(gè)Bucket可以記錄1秒內(nèi)的數(shù)據(jù),也可以記錄10毫秒內(nèi)的數(shù)據(jù),這由采樣周期決定。采樣周期就是每個(gè)Bucket的時(shí)間窗口大小。
WindowWrap,用于記錄Bucket的時(shí)間窗口信息(包括時(shí)間窗口的開(kāi)始時(shí)間戳和大小),而WindowWrap數(shù)組就是一個(gè)滑動(dòng)窗口。當(dāng)收到一個(gè)請(qǐng)求時(shí),可以根據(jù)收到請(qǐng)求時(shí)的時(shí)間戳和滑動(dòng)窗口大小計(jì)算出一個(gè)索引值,從滑動(dòng)窗口(WindowWrap數(shù)組)中獲取一個(gè)WindowWrap類,從而獲取WindowWrap類包裝的Bucket,并調(diào)用Bucket實(shí)例的add方法統(tǒng)計(jì)指標(biāo)。
LeapArray,Sentinel 中統(tǒng)計(jì)指標(biāo)的基本數(shù)據(jù)結(jié)構(gòu)?;诨瑒?dòng)窗口算法來(lái)計(jì)算數(shù)據(jù)返回windowWrap時(shí)間窗口對(duì)象。前面說(shuō)的兩個(gè)問(wèn)題在這個(gè)數(shù)據(jù)結(jié)構(gòu)里面都有對(duì)應(yīng)的算法實(shí)現(xiàn),當(dāng)然還有別的統(tǒng)計(jì)算法,但最后都是算時(shí)間窗口。
腦圖概覽

原文鏈接:https://www.dianjilingqu.com/741711.html