什么是服務(wù)熔斷?

一、什么是服務(wù)熔斷?

熔斷這一概念來源于電子工程中的斷路器(Circuit Breaker)。

在互聯(lián)網(wǎng)系統(tǒng)中,當(dāng)下游服務(wù)因訪問壓力過大而響應(yīng)變慢或失敗,上游服務(wù)為了保護(hù)系統(tǒng)整體的可用性,可以暫時(shí)切斷對(duì)下游服務(wù)的調(diào)用。

這種犧牲局部,保全整體的措施就叫做熔斷。

如果不采取熔斷措施,我們的系統(tǒng)會(huì)怎樣呢?

我們來看一個(gè)栗子。

當(dāng)前系統(tǒng)中有A,B,C三個(gè)服務(wù),服務(wù)A是上游,服務(wù)B是中游,服務(wù)C是下游。

它們的調(diào)用鏈如下:


image

一旦下游服務(wù)C因某些原因變得不可用,積壓了大量請(qǐng)求,服務(wù)B的請(qǐng)求線程也隨之阻塞。線程資源逐漸耗盡,使得服務(wù)B也變得不可用。緊接著,服務(wù) A也變?yōu)椴豢捎?,整個(gè)調(diào)用鏈路被拖垮。

image

像這種調(diào)用鏈路的連鎖故障,叫做雪崩

二、熔斷機(jī)制實(shí)際應(yīng)用

三個(gè)狀態(tài)的轉(zhuǎn)化關(guān)系如下圖:


image

1、背景

針對(duì)所有二級(jí)及以下上游依賴服務(wù)提供熔斷機(jī)制,保障商城整體可用行

2、名詞解釋

(1)斷路器(Breaker):

一種設(shè)計(jì)模式,在特定情況下,可以對(duì)即將執(zhí)行一個(gè)或一組函數(shù)起到攔截作用,并直接返回預(yù)定結(jié)果。在服務(wù)熔斷中主要用來判斷上游服務(wù)是否可用,并決定是否進(jìn)行調(diào)用

(2)斷路器的三種狀態(tài)

開啟: 當(dāng)調(diào)用上游服務(wù)持續(xù)發(fā)送異常并達(dá)到指定閾值,程序會(huì)將斷路器置為此狀態(tài),此狀態(tài)下代表上游服務(wù)不可用,斷路器會(huì)攔截該服務(wù)的調(diào)用。

關(guān)閉:默認(rèn)為此狀態(tài),代表上游服務(wù)可用,此狀態(tài)下斷路器不作為

半開:但熔斷器處于開啟狀態(tài)達(dá)到重試時(shí)間之后,斷路器會(huì)置為此狀態(tài),此狀態(tài)下會(huì)對(duì)上游服務(wù)進(jìn)行重試,成功,則重置為關(guān)閉狀態(tài)。失敗,則再次置為開啟狀態(tài)

3、實(shí)現(xiàn)方案

(1)基于切面實(shí)現(xiàn),在Adapter層切入,優(yōu)先級(jí)小于降級(jí)邏輯

(2)調(diào)用服務(wù)之前判斷當(dāng)前服務(wù)斷路器的狀態(tài),開啟則直接返回;半開或關(guān)閉則執(zhí)行調(diào)用

(3)調(diào)用服務(wù)之后對(duì)結(jié)果進(jìn)行斷言,并進(jìn)行數(shù)據(jù)分析,重置斷路器的狀態(tài),寫入共享內(nèi)存

在worker進(jìn)程的做法:


image

在自定義進(jìn)程的做法:


image.png
image.png

4、進(jìn)程職責(zé)劃分
(1)worker進(jìn)程:根據(jù)斷路器狀態(tài)判斷是否請(qǐng)求上游服務(wù);對(duì)請(qǐng)求數(shù)、失敗數(shù)、重試數(shù)、成功數(shù)進(jìn)行計(jì)數(shù);
(2)管理進(jìn)程:循環(huán)調(diào)用,分析當(dāng)前時(shí)間段的數(shù)據(jù),切換斷路器狀態(tài);失敗率上報(bào);熔斷、恢復(fù)通知發(fā)送;刪除過期數(shù)據(jù);

5、接入方式
theone(swoole):
1.使用swoole\table共享內(nèi)存存儲(chǔ)數(shù)據(jù),server啟動(dòng)之前初始化共享內(nèi)存
2.添加自定義熔斷管理進(jìn)程
3.基于AOP理念,切入Adapter層(調(diào)用上游接口類),在請(qǐng)求之前校驗(yàn),在請(qǐng)求之后計(jì)數(shù)
mall-api(swoole+yii):
1.使用swoole\table共享內(nèi)存存儲(chǔ)數(shù)據(jù),server啟動(dòng)之前初始化共享內(nèi)存
2.添加自定義熔斷管理進(jìn)程
3.代碼侵入至ApiRpcCall::beforeCoRequest和ApiRpcCall::afterCoRequest兩個(gè)鉤子函數(shù)中,實(shí)現(xiàn)熔斷和計(jì)數(shù)
fpm模式:
非swoole模式,可以使用yac擴(kuò)展實(shí)現(xiàn)請(qǐng)求計(jì)數(shù)

6、上報(bào)
(1)釘釘消息:當(dāng)某個(gè)服務(wù)被熔斷或恢復(fù)時(shí),由當(dāng)前worker進(jìn)程異步發(fā)送通知到釘釘群組,開發(fā)人員可立即感知
(2)上報(bào)OPS:將某個(gè)服務(wù)的失敗率(失敗數(shù)/請(qǐng)求數(shù))上報(bào)至ops,由管理進(jìn)程處理,每分鐘上報(bào)一次??梢暬^察服務(wù)的可用性。

7、人工干預(yù)
(1)配置中心:當(dāng)某個(gè)服務(wù)觸發(fā)熔斷時(shí),可能不符合我們的預(yù)期,需要強(qiáng)制開啟針對(duì)該服務(wù)的調(diào)用。更改商城配置中心的配置,在斷路器執(zhí)行開始時(shí),判斷該服務(wù)的配置判斷是否繼續(xù)熔斷。

8、問題
(1)上游服務(wù)請(qǐng)求失敗的判斷標(biāo)準(zhǔn)
只處理請(qǐng)求超時(shí)和耗時(shí)較長(zhǎng)的情況,不考慮httpCode和errCode
存在上游服務(wù)被限流,返回的錯(cuò)誤狀態(tài)碼
(2)當(dāng)前時(shí)間點(diǎn)的失敗率如何計(jì)算
1)用前一分鐘的失敗率;即 04'30''請(qǐng)求失敗,使用03'00''~03'59''的失敗數(shù)/請(qǐng)求數(shù)作為失敗率;(反應(yīng)有延遲)
2)用當(dāng)前分鐘+前一分鐘總合計(jì)算;即4'30''請(qǐng)求失敗,使用4'00''4'30''的+03'00''03'59''的失敗數(shù)/請(qǐng)求數(shù)作為失敗率(時(shí)間跨度不一致)

6、代碼目錄結(jié)構(gòu)

image.png

斷路器狀態(tài)接口:實(shí)現(xiàn) -- 開啟 關(guān)閉 半開
數(shù)據(jù)模型接口:實(shí)現(xiàn) -- swoole fpm
消息通知接口:實(shí)現(xiàn) -- 釘釘 ops
斷路器管理程序:一些基本屬性 + 斷路器狀態(tài)注入 數(shù)據(jù)模型注入 消息通知注入

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容