談?wù)劮?wù)雪崩、降級與熔斷

引言

首先,之所以談這個話題呢,是發(fā)現(xiàn)現(xiàn)在很多人對微服務(wù)的設(shè)計(jì)缺乏認(rèn)識,所以寫一篇掃盲文。當(dāng)然,考慮到目前大多微服務(wù)的文章都是口水文,煙哥爭取將實(shí)現(xiàn)方式講透,點(diǎn)清楚,讓大家有所收獲!

OK,我要先說明一下,我有很長一段時間將服務(wù)降級服務(wù)熔斷混在一起,認(rèn)為是一回事!

為什么我會有這樣的誤解呢?

針對下面的情形,如圖所示

當(dāng)Service A調(diào)用Service B,失敗多次達(dá)到一定閥值,Service A不會再去調(diào)Service B,而會去執(zhí)行本地的降級方法!

對于這么一套機(jī)制:在Spring cloud中結(jié)合Hystrix,將其稱為熔斷降級!

所以我當(dāng)時就以為是一回事了,畢竟熔斷和降級是一起發(fā)生的,而且這二者的概念太相近了!后面接觸了多了,發(fā)現(xiàn)自己理解的還是太狹隘了,因此本文中帶著點(diǎn)我自己的見解,大家如果有不同意見,請輕噴!畢竟還有很多人認(rèn)為兩者是一致的!

正文

服務(wù)雪崩

OK,我們從服務(wù)雪崩開始講起!假設(shè)存在如下調(diào)用鏈

而此時,Service A的流量波動很大,流量經(jīng)常會突然性增加!那么在這種情況下,就算Service A能扛得住請求,Service B和Service C未必能扛得住這突發(fā)的請求。

此時,如果Service C因?yàn)榭共蛔≌埱?,變得不可用。那么Service B的請求也會阻塞,慢慢耗盡Service B的線程資源,Service B就會變得不可用。緊接著,Service A也會不可用,這一過程如下圖所示

如上圖所示,一個服務(wù)失敗,導(dǎo)致整條鏈路的服務(wù)都失敗的情形,我們稱之為服務(wù)雪崩。

ps:誰發(fā)明的這個詞,真是面試裝13必備!

那么,服務(wù)熔斷和服務(wù)降級就可以視為解決服務(wù)雪崩的手段之一。

服務(wù)熔斷

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

服務(wù)熔斷:當(dāng)下游的服務(wù)因?yàn)槟撤N原因突然變得不可用響應(yīng)過慢,上游服務(wù)為了保證自己整體服務(wù)的可用性,不再繼續(xù)調(diào)用目標(biāo)服務(wù),直接返回,快速釋放資源。如果目標(biāo)服務(wù)情況好轉(zhuǎn)則恢復(fù)調(diào)用。

需要說明的是熔斷其實(shí)是一個框架級的處理,那么這套熔斷機(jī)制的設(shè)計(jì),基本上業(yè)內(nèi)用的是斷路器模式,如Martin Fowler提供的狀態(tài)轉(zhuǎn)換圖如下所示

最開始處于closed狀態(tài),一旦檢測到錯誤到達(dá)一定閾值,便轉(zhuǎn)為open狀態(tài);

這時候會有個 reset timeout,到了這個時間了,會轉(zhuǎn)移到half open狀態(tài);

嘗試放行一部分請求到后端,一旦檢測成功便回歸到closed狀態(tài),即恢復(fù)服務(wù);

業(yè)內(nèi)目前流行的熔斷器很多,例如阿里出的Sentinel,以及最多人使用的Hystrix

在Hystrix中,對應(yīng)配置如下

//滑動窗口的大小,默認(rèn)為20

circuitBreaker.requestVolumeThreshold

//過多長時間,熔斷器再次檢測是否開啟,默認(rèn)為5000,即5s鐘

circuitBreaker.sleepWindowInMilliseconds

//錯誤率,默認(rèn)50%

circuitBreaker.errorThresholdPercentage

每當(dāng)20個請求中,有50%失敗時,熔斷器就會打開,此時再調(diào)用此服務(wù),將會直接返回失敗,不再調(diào)遠(yuǎn)程服務(wù)。直到5s鐘之后,重新檢測該觸發(fā)條件,判斷是否把熔斷器關(guān)閉,或者繼續(xù)打開。

這些屬于框架層級的實(shí)現(xiàn),我們只要實(shí)現(xiàn)對應(yīng)接口就好!

服務(wù)降級

那么,什么是服務(wù)降級呢?

這里有兩種場景:

當(dāng)下游的服務(wù)因?yàn)槟撤N原因響應(yīng)過慢,下游服務(wù)主動停掉一些不太重要的業(yè)務(wù),釋放出服務(wù)器資源,增加響應(yīng)速度!

當(dāng)下游的服務(wù)因?yàn)槟撤N原因不可用,上游主動調(diào)用本地的一些降級邏輯,避免卡頓,迅速返回給用戶!

其實(shí)乍看之下,很多人還是不懂熔斷和降級的區(qū)別!

其實(shí)應(yīng)該要這么理解:

服務(wù)降級有很多種降級方式!如開關(guān)降級、限流降級、熔斷降級!

服務(wù)熔斷屬于降級方式的一種!

可能有的人不服,覺得熔斷是熔斷、降級是降級,分明是兩回事??!其實(shí)不然,因?yàn)閺膶?shí)現(xiàn)上來說,熔斷和降級必定是一起出現(xiàn)。因?yàn)楫?dāng)發(fā)生下游服務(wù)不可用的情況,這個時候?yàn)榱藢ψ罱K用戶負(fù)責(zé),就需要進(jìn)入上游的降級邏輯了。因此,將熔斷降級視為降級方式的一種,也是可以說的通的!

我撇開框架,以最簡單的代碼來說明!上游代碼如下

try{

//調(diào)用下游的helloWorld服務(wù)

xxRpc.helloWorld();

}catch(Exception e){

//因?yàn)槿蹟?,所以調(diào)不通

doSomething();

}

注意看,下游的helloWorld服務(wù)因?yàn)槿蹟喽{(diào)不通。此時上游服務(wù)就會進(jìn)入catch里頭的代碼塊,那么catch里頭執(zhí)行的邏輯,你就可以理解為降級邏輯!

什么,你跟我說你不捕捉異常,直接丟頁面?

OK,那我甘拜下風(fēng),當(dāng)我理解錯誤!

服務(wù)降級大多是屬于一種業(yè)務(wù)級別的處理。當(dāng)然,我這里要講的是另一種降級方式,也就是開關(guān)降級!這也是我們生產(chǎn)上常用的另一種降級方式!

做法很簡單,做個開關(guān),然后將開關(guān)放配置中心!在配置中心更改開關(guān),決定哪些服務(wù)進(jìn)行降級。至于配置變動后,應(yīng)用怎么監(jiān)控到配置發(fā)生了變動,這就不是本文該討論的范圍。

那么,在應(yīng)用程序中部下開關(guān)的這個過程,業(yè)內(nèi)也有一個名詞,稱為埋點(diǎn)!

那接下來最關(guān)鍵的一個問題,哪些業(yè)務(wù)需要埋點(diǎn)?

一般有以下方法

(1)簡化執(zhí)行流程

自己梳理出核心業(yè)務(wù)流程和非核心業(yè)務(wù)流程。然后在非核心業(yè)務(wù)流程上加上開關(guān),一旦發(fā)現(xiàn)系統(tǒng)扛不住,關(guān)掉開關(guān),結(jié)束這些次要流程。

(2)關(guān)閉次要功能

一個微服務(wù)下肯定有很多功能,那自己區(qū)分出主要功能和次要功能。然后次要功能加上開關(guān),需要降級的時候,把次要功能關(guān)了吧!

(3)降低一致性

假設(shè),你在業(yè)務(wù)上發(fā)現(xiàn)執(zhí)行流程沒法簡化了,愁??!也沒啥次要功能可以關(guān)了,桑心啊!那只能降低一致性了,即將核心業(yè)務(wù)流程的同步改異步,將強(qiáng)一致性改最終一致性!

可是這些都是手動降級,有辦法自動降級么?

這里我摸著良心說,我們在生產(chǎn)上沒弄自動降級!因?yàn)橐话阈枰导壍膱鼍?,都是可以預(yù)見的,例如某某活動。假設(shè),平時真的有突發(fā)事件,流量異常,也有監(jiān)控系統(tǒng)發(fā)郵件通知,提醒我們?nèi)ソ导墸?/p>

當(dāng)然,這并不代表自動降級不能做,因此以下內(nèi)容可以認(rèn)為我在胡說八道,因?yàn)槲以谏a(chǎn)上沒實(shí)踐過,只是頭腦大概想了下,如果讓我來做自動降級我會怎么實(shí)現(xiàn):

(1)自己設(shè)一個閾值,例如幾秒內(nèi)失敗多少次,就啟動降級

(2)自己做接口監(jiān)控(有興趣的可以了解一下Rxjava),達(dá)到閾值就走推送邏輯。怎么推呢?比如你配置是放在git上,就用jgit去改配置中心的配置。如果配置放數(shù)據(jù)庫,就用jdbc去改。

(3)改完配置中心的配置后,應(yīng)用就可以自動檢測到配置的變化,進(jìn)行降級!(這句不了解的,了解一下配置中心的熱刷新功能)

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

相關(guān)閱讀更多精彩內(nèi)容

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