分布式系統(tǒng)關(guān)注點(diǎn)——99%的人都能看懂的「熔斷」以及最佳實(shí)踐

      網(wǎng)友投稿 735 2025-03-31

      如果這是第二次看到我的文章,歡迎關(guān)注我喲~

      本文長度為3319字,建議閱讀9分鐘。

      當(dāng)我們工作所在的系統(tǒng)處于分布式系統(tǒng)初期的時(shí)候,往往這時(shí)候每個(gè)服務(wù)都只部署了一個(gè)節(jié)點(diǎn)。

      那么在這樣的背景下,如果某個(gè)服務(wù)A需要發(fā)布一個(gè)新版本,往往會(huì)對(duì)正在運(yùn)行的其它依賴服務(wù)A的程序產(chǎn)生影響。甚至,一旦服務(wù)A的啟動(dòng)預(yù)熱過程耗時(shí)過長,問題會(huì)更嚴(yán)重,大量請(qǐng)求會(huì)阻塞,產(chǎn)生級(jí)聯(lián)影響,導(dǎo)致整個(gè)系統(tǒng)卡慢。

      ▲點(diǎn)擊圖片可查看大圖

      舉個(gè)夸張的例子來形容:一幢樓的下水管是從最高樓直通到最低樓的,這個(gè)時(shí)候如果你家樓下的管道口堵住了,那么所有樓上的污水就會(huì)倒灌到你家。如果這導(dǎo)致你家的管道口也堵住了,之后又會(huì)倒灌到樓上一層,以此類推。

      然而實(shí)際生活中一旦你發(fā)現(xiàn)了這個(gè)問題,必然會(huì)想辦法先避免影響到自己家,然后跑到樓下讓他們趕緊疏通管道。此時(shí),避免影響自己家的辦法就可被稱之為「熔斷」。

      一、熔斷是什么

      熔斷本質(zhì)上是一個(gè)過載保護(hù)機(jī)制。這一概念來源于電子工程中的斷路器,可能你曾經(jīng)被這個(gè)東西的“跳閘”保護(hù)過。

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

      做熔斷的思路大體上就是:一個(gè)中心思想,分四步走。

      二、熔斷怎么做

      首先,需秉持的一個(gè)中心思想是:量力而行。因?yàn)檐浖腿瞬煌瑳]有奇跡會(huì)發(fā)生,什么樣的性能撐多少流量是固定的。這是根本。

      然后,這四步走分別是:

      定義一個(gè)識(shí)別是否處于“不可用”狀態(tài)的策略

      切斷聯(lián)系

      定義一個(gè)識(shí)別是否處于“可用”狀態(tài)的策略,并嘗試探測

      重新恢復(fù)正常

      定義一個(gè)識(shí)別是否處于“不正常”狀態(tài)的策略

      相信軟件開發(fā)經(jīng)驗(yàn)豐富的你也知道,識(shí)別一個(gè)系統(tǒng)是否正常,無非是兩個(gè)點(diǎn)。

      是不是能調(diào)通

      如果能調(diào)通,耗時(shí)是不是超過預(yù)期的長

      但是,由于分布式系統(tǒng)被建立在一個(gè)并不是100%可靠的網(wǎng)絡(luò)上,所以上述的情況總有發(fā)生,因此我們不能將偶發(fā)的瞬時(shí)異常等同于系統(tǒng)“不可用”(避免以偏概全)。由此我們需要引入一個(gè)「時(shí)間窗口」的概念,這個(gè)時(shí)間窗口用來“放寬”判定“不可用”的區(qū)間,也意味著多給了系統(tǒng)幾次證明自己“可用”機(jī)會(huì)。但是,如果系統(tǒng)還是在這個(gè)時(shí)間窗口內(nèi)達(dá)到了你定義“不可用”標(biāo)準(zhǔn),那么我們就要“斷臂求生”了。

      這個(gè)標(biāo)準(zhǔn)可以有兩種方式來指定。

      閾值。比如,在10秒內(nèi)出現(xiàn)100次“無法連接”或者出現(xiàn)100次大于5秒的請(qǐng)求。

      百分比。比如,在10秒內(nèi)有30%請(qǐng)求“無法連接”或者30%的請(qǐng)求大于5秒。

      最終會(huì)形成這樣這樣的一段代碼。

      分布式系統(tǒng)關(guān)注點(diǎn)——99%的人都能看懂的「熔斷」以及最佳實(shí)踐

      全局變量?errorcount?=?0;?//有個(gè)獨(dú)立的線程每隔10秒(時(shí)間窗口)重置為0。 全局變量?isOpenCircuitBreaker?=?false; //do?some?thing... if(success){ ????return?success; } else{ ????errorcount++; ????if(errorcount?==?不可用閾值){ ????????isOpenCircuitBreaker?=?true; ????} }

      切斷聯(lián)系

      切斷聯(lián)系要盡可能的“果斷”,既然已經(jīng)認(rèn)定了對(duì)方“不可用”,那么索性就默認(rèn)“失敗”,避免做無用功,也順帶能緩解對(duì)方的壓力。

      分布式系統(tǒng)中的程序間調(diào)用,一般都會(huì)通過一些RPC框架進(jìn)行。

      那么,這個(gè)時(shí)候作為客戶端一方,在自己進(jìn)程內(nèi)通過代理發(fā)起調(diào)用之前就可以直接返回失敗,不走網(wǎng)絡(luò)。

      這就是常說的「fail fast」機(jī)制。就是在前面提到的代碼段之前增加下面的這段代碼。

      if(isOpenCircuitBreaker?==?true){ ????return?fail; } //do?some?thing...

      定義一個(gè)識(shí)別是否處于“可用”狀態(tài)的策略,并嘗試探測

      切斷聯(lián)系后,功能的完整性必然會(huì)受影響,所以還是需要盡快恢復(fù)回來,以提供完整的服務(wù)能力。這事肯定不能人為去干預(yù),及時(shí)性必然會(huì)受到影響。那么如何能夠自動(dòng)的識(shí)別依賴系統(tǒng)是否“可用”呢?這也需要你來定義一個(gè)策略。

      一般來說這個(gè)策略與識(shí)別“不可用”的策略類似,只是這里是一個(gè)反向指標(biāo)。

      閾值。比如,在10秒內(nèi)出現(xiàn)100次“調(diào)用成功”并且耗時(shí)都小于1秒。

      百分比。比如,在10秒內(nèi)有95%請(qǐng)求“調(diào)用成功”并且98%的請(qǐng)求小于1秒。

      同樣包含「時(shí)間窗口」、「閾值」以及「百分比」。

      稍微不同的地方在于,大多數(shù)情況下,一個(gè)系統(tǒng)“不可用”的狀態(tài)往往會(huì)持續(xù)一段時(shí)間,不會(huì)那么快就恢復(fù)過來。所以我們不需要像第一步中識(shí)別“不可用”那樣,無時(shí)無刻的記錄請(qǐng)求狀況,而只需要在每隔一段時(shí)間之后去進(jìn)行探測即可。所以,這里多了一個(gè)「間隔時(shí)間」的概念。這個(gè)間隔幅度可以是固定的,比如30秒。也可以是動(dòng)態(tài)增加的,通過線性增長或者指數(shù)增長等方式。

      這個(gè)用代碼表述大致是這樣。

      全局變量?successCount?=?0;? //有個(gè)獨(dú)立的線程每隔10秒(時(shí)間窗口)重置為0。 //并且將下面的isHalfOpen設(shè)為false。 全局變量?isHalfOpen?=?true;//有個(gè)獨(dú)立的線程每隔30秒(間隔時(shí)間)重置為true。 //do?some?thing... if(success){ ????if(isHalfOpen){ ????????successCount?++; ????????if(successCount?=?可用閾值){ ????????????isOpenCircuitBreaker?=?false; ????????} ????}???? ????return?success; } else{ ????errorcount++; ????if(errorcount?==?不可用閾值){ ????????isOpenCircuitBreaker?=?true; ????} }

      另外,嘗試探測本質(zhì)上是一個(gè)“試錯(cuò)”,要控制下“試錯(cuò)成本”。所以我們不可能拿100%的流量去驗(yàn)證,一般會(huì)有以下兩種方式:

      放行一定比例的流量去驗(yàn)證。

      如果在整個(gè)通信框架都是統(tǒng)一的情況下,還可以統(tǒng)一給每個(gè)系統(tǒng)增加一個(gè)專門用于驗(yàn)證程序健康狀態(tài)檢測的獨(dú)立接口。這個(gè)接口額外可以多返回一些系統(tǒng)負(fù)載信息用于判斷健康狀態(tài),如CPU、I/O的情況等。

      重新恢復(fù)正常

      一旦通過了衡量是否“可用”的驗(yàn)證,整個(gè)系統(tǒng)就恢復(fù)到了“正常”狀態(tài),此時(shí)需要重新開啟識(shí)別“不可用”的策略。就這樣,系統(tǒng)會(huì)形成一個(gè)循環(huán)。

      ▲點(diǎn)擊圖片可查看大圖

      這就是一個(gè)完整的熔斷機(jī)制的面貌。了解了這些核心思想,用什么框架去實(shí)施就變得不是那么重要了,因?yàn)榇蟛糠侄际菗Q湯不換藥。

      上面聊到的這些可以說是主干部分,還有一些最佳實(shí)踐可以讓你在實(shí)施熔斷的時(shí)候拿捏的更到位。

      三、做熔斷的最佳實(shí)踐

      什么場景最適合做熔斷

      一個(gè)事物在不同的場景里會(huì)發(fā)揮出不同的效果。以下是我能想到最適合熔斷發(fā)揮更大優(yōu)勢的幾個(gè)場景:

      所依賴的系統(tǒng)本身是一個(gè)共享系統(tǒng),當(dāng)前客戶端只是其中的一個(gè)客戶端。這是因?yàn)椋绻渌蛻舳诉M(jìn)行胡亂調(diào)用也會(huì)影響到你的調(diào)用。

      所以依賴的系統(tǒng)被部署在一個(gè)共享環(huán)境中(資源未做隔離),并不獨(dú)占使用。比如,和某個(gè)高負(fù)荷的數(shù)據(jù)庫在同一臺(tái)服務(wù)器上。

      所依賴的系統(tǒng)是一個(gè)經(jīng)常會(huì)迭代更新的服務(wù)。這點(diǎn)也意味著,越“敏捷”的系統(tǒng)越需要“熔斷”。

      當(dāng)前所在的系統(tǒng)流量大小是不確定的。比如,一個(gè)電商網(wǎng)站的流量波動(dòng)會(huì)很大,你能抗住突增的流量不代表所依賴的后端系統(tǒng)也能抗住。這點(diǎn)也反映出了我們?cè)?a target="_blank" href="http://m.bai1xia.com/news/tags-6728.html"style="font-weight:bold;">軟件設(shè)計(jì)中帶著“面向懷疑”的心態(tài)的重要性。

      做熔斷時(shí)還要注意的一些地方

      與所有事物一樣,熔斷也不是一個(gè)完美的事物,我們特別需要注意2個(gè)問題。

      首先,如果所依賴的系統(tǒng)是多副本或者做了分區(qū)的,那么要注意其中個(gè)別節(jié)點(diǎn)的異常并不等于所有節(jié)點(diǎn)都存在異常,所以需要區(qū)別對(duì)待。

      其次,熔斷往往應(yīng)作為最后的選擇,我們應(yīng)優(yōu)先使用一些「降級(jí)」或者「限流」方案。因?yàn)椤安糠謩儆跓o”,雖然無法提供完整的服務(wù),但盡可能的降低影響是要持續(xù)去努力的。比如,拋棄非核心業(yè)務(wù)、給出友好提示等等,這部分內(nèi)容我們會(huì)在后續(xù)的文章中展開。

      四、總結(jié)

      本文主要聊了熔斷的作用以及做法,并且總結(jié)了一些我自己的最佳實(shí)踐。

      上面的這些代碼示例中也可以看到,熔斷代碼所在的位置要么在實(shí)際方法之前,要么在實(shí)際方法之后。它非常適合AOP編程思想的發(fā)揮,所以我們平常用到的熔斷框架都會(huì)基于AOP去做。

      熔斷只是一個(gè)保護(hù)殼,在周圍出現(xiàn)異常的時(shí)候保全自身。但是從長遠(yuǎn)來看平時(shí)定期做好壓力測試才能更好的防范于未然,降低觸發(fā)熔斷的次數(shù)。如果清楚的知道每個(gè)系統(tǒng)有幾斤幾兩,在這個(gè)基礎(chǔ)上再把「限流」和「降級(jí)」做好,這基本就將“高壓”下觸發(fā)熔斷的概率降到最低了。

      Question:

      你覺得還有什么時(shí)候需要熔斷呢?歡迎給我留言交流哦。

      相關(guān)文章:

      分布式系統(tǒng)關(guān)注點(diǎn)——僅需這一篇,吃透「負(fù)載均衡」妥妥的

      過去這幾十年,分布式系統(tǒng)的「數(shù)據(jù)一致性」精華都在這了!

      微信公眾號(hào)(首發(fā)):跨界架構(gòu)師。<-- 點(diǎn)擊后閱讀熱門文章,或掃碼關(guān)注 -->

      定期發(fā)表原創(chuàng)內(nèi)容:架構(gòu)設(shè)計(jì)丨分布式系統(tǒng)丨產(chǎn)品丨運(yùn)營丨一些深度思考。

      分布式

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。

      上一篇:進(jìn)銷存軟件有哪些?進(jìn)銷存軟件排行榜
      下一篇:excel求排名(excel求排名怎么操作)
      相關(guān)文章
      婷婷久久久亚洲欧洲日产国码AV | 亚洲国产精品免费观看 | 亚洲国产成人AV网站| 国产91在线|亚洲| 亚洲国产美女精品久久久久| 99久久亚洲精品无码毛片| 亚洲人成在线观看| 亚洲一区二区三区日本久久九| 亚洲AV无码久久精品色欲| 亚洲成a人片在线观看无码 | jlzzjlzz亚洲jzjzjz| 亚洲欧洲日韩国产一区二区三区| 亚洲一区二区久久| 亚洲人成综合网站7777香蕉| 亚洲国产视频久久| 亚洲经典千人经典日产| 爱情岛亚洲论坛在线观看| 亚洲国产精品尤物YW在线观看| 亚洲国产精品成人一区| 亚洲午夜日韩高清一区| 亚洲综合无码精品一区二区三区| 亚洲乱码一区二区三区在线观看 | 亚洲国产精品特色大片观看完整版| 亚洲熟女一区二区三区| 亚洲国产精品SSS在线观看AV| 亚洲国产国产综合一区首页| 久久亚洲精品无码AV红樱桃| 亚洲春色另类小说| 中文字幕亚洲码在线| 亚洲AV无码一区二区三区鸳鸯影院| 另类小说亚洲色图| 国产乱辈通伦影片在线播放亚洲 | 亚洲AV永久无码精品一区二区国产| 亚洲精品国产精品国自产观看| 国产成人精品曰本亚洲79ren| 亚洲日本一区二区三区在线 | 亚洲AV无码国产精品永久一区| 亚洲国产综合精品中文字幕| 亚洲欧洲自拍拍偷午夜色无码| 久久久久久久久亚洲| 亚洲国产精品综合久久网各|