【了解】熔斷限流
熔斷限流降級(jí)
熔斷、限流、降級(jí)都是保持系統(tǒng)穩(wěn)定運(yùn)行的策略,但針對(duì)的場(chǎng)景有所不同。
熔斷
服務(wù)熔斷的作用類似于我們家用的保險(xiǎn)絲,當(dāng)某服務(wù)出現(xiàn)不可用或響應(yīng)超時(shí)的情況時(shí),為了防止整個(gè)系統(tǒng)出現(xiàn)雪崩,暫時(shí)停止對(duì)該服務(wù)的調(diào)用。

上面的解釋中有兩個(gè)很關(guān)鍵的詞,一個(gè)是暫時(shí),一個(gè)是停止。
停止是說,當(dāng)前服務(wù)一旦對(duì)下游服務(wù)進(jìn)行熔斷,當(dāng)請(qǐng)求到達(dá)時(shí),當(dāng)前服務(wù)不再對(duì)下游服務(wù)進(jìn)行調(diào)用,而是使用設(shè)定好的策略 (如構(gòu)建默認(rèn)值)直接返回。
暫時(shí)是說,熔斷后,并不會(huì)一直不再調(diào)用下游服務(wù),而是以一定的策略 (如每分鐘調(diào)用 10 次,若均返回成功,則增大調(diào)用量)試探調(diào)用下游服務(wù),當(dāng)下游服務(wù)恢復(fù)可用時(shí), 自動(dòng)停止熔斷 。
如上圖,當(dāng) ServiceD 不可用時(shí),ServiceB 應(yīng)對(duì) ServiceD 進(jìn)行熔斷。
限流
限流是指上游服務(wù)對(duì)本服務(wù)請(qǐng)求 QPS 超過闕值時(shí),通過一定的策略(如延遲處理、拒絕處理)對(duì)上游服務(wù)的請(qǐng)求量進(jìn)行限制,以保證本服務(wù)不被壓垮,從而持續(xù)提供穩(wěn)定服務(wù)。常見的限流算法有滑動(dòng)窗口、令牌桶、漏桶等。
如上圖,當(dāng) ServiceB 對(duì) ServiceD 請(qǐng)求過多時(shí),ServiceD 可以放棄一部分請(qǐng)求,保證自身服務(wù)的穩(wěn)定。
限流指標(biāo)
TPS
系統(tǒng)吞吐量是衡量系統(tǒng)性能的關(guān)鍵指標(biāo),按照事務(wù)的完成數(shù)量來(lái)限流是最合理的。
但是對(duì)實(shí)操性來(lái)說,按照事務(wù)來(lái)限流并不現(xiàn)實(shí)。在分布式系統(tǒng)中完成一筆事務(wù)需要多個(gè)系統(tǒng)的配合。比如我們?cè)陔娚滔到y(tǒng)購(gòu)物,需要訂單、庫(kù)存、賬戶、支付等多個(gè)服務(wù)配合完成,有的服務(wù)需要異步返回,這樣完成一筆事務(wù)花費(fèi)的時(shí)間可能會(huì)很長(zhǎng)。如果按照TPS來(lái)進(jìn)行限流,時(shí)間粒度可能會(huì)很大大,很難準(zhǔn)確評(píng)估系統(tǒng)的響應(yīng)性能。
HPS
每秒請(qǐng)求數(shù),指每秒鐘服務(wù)端收到客戶端的請(qǐng)求數(shù)量。
如果一個(gè)請(qǐng)求完成一筆事務(wù),那TPS和HPS是等同的。但在分布式場(chǎng)景下,完成一筆事務(wù)可能需要多次請(qǐng)求,所以TPS和HPS指標(biāo)不能等同看待。
QPS
服務(wù)端每秒能夠響應(yīng)的客戶端查詢請(qǐng)求數(shù)量。
如果后臺(tái)只有一臺(tái)服務(wù)器,那HPS和QPS是等同的。但是在分布式場(chǎng)景下,每個(gè)請(qǐng)求需要多個(gè)服務(wù)器配合完成響應(yīng)。
目前主流的限流方法多采用HPS作為限流指標(biāo)。
限流方法
流量計(jì)數(shù)器
這是最簡(jiǎn)單直接的方法,比如限制每秒請(qǐng)求數(shù)量100,超過100的請(qǐng)求就拒絕掉。
但是這個(gè)方法存在2個(gè)明顯的問題:
-
單位時(shí)間(比如1s)很難把控,如下圖:
-
這張圖上,從下面時(shí)間看,HPS沒有超過100,但是從上面看HPS超過100了。
-
有一段時(shí)間流量超了,也不一定真的需要限流,如下圖,系統(tǒng)HPS限制50,雖然前3s流量超了,但是如果讀超時(shí)時(shí)間設(shè)置為5s,并不需要限流。

滑動(dòng)時(shí)間窗口
滑動(dòng)時(shí)間窗口算法是目前比較流行的限流算法,主要思想是把時(shí)間看做是一個(gè)向前滾動(dòng)的窗口,如下圖:
開始的時(shí)候,我們把t1~t5看做一個(gè)時(shí)間窗口,每個(gè)窗口1s,如果我們定的限流目標(biāo)是每秒50個(gè)請(qǐng)求,那t1~t5這個(gè)窗口的請(qǐng)求總和不能超過250個(gè)。
這個(gè)窗口是滑動(dòng)的,下一秒的窗口成了t2~t6,這時(shí)把t1時(shí)間片的統(tǒng)計(jì)拋棄,加入t6時(shí)間片進(jìn)行統(tǒng)計(jì)。這段時(shí)間內(nèi)的請(qǐng)求數(shù)量也不能超過250個(gè)。
滑動(dòng)時(shí)間窗口的優(yōu)點(diǎn)是解決了流量計(jì)數(shù)器算法的缺陷,但是也有2個(gè)問題:
- 流量超過就必須拋棄或者走降級(jí)邏輯
- 對(duì)流量控制不夠精細(xì),不能限制集中在短時(shí)間內(nèi)的流量,也不能削峰填谷
漏桶算法
漏桶算法的思想如下圖:
在客戶端的請(qǐng)求發(fā)送到服務(wù)器之前,先用漏桶緩存起來(lái),這個(gè)漏桶可以是一個(gè)長(zhǎng)度固定的隊(duì)列,這個(gè)隊(duì)列中的請(qǐng)求均勻的發(fā)送到服務(wù)端。
如果客戶端的請(qǐng)求速率太快,漏桶的隊(duì)列滿了,就會(huì)被拒絕掉,或者走降級(jí)處理邏輯。這樣服務(wù)端就不會(huì)受到突發(fā)流量的沖擊。
漏桶算法的優(yōu)點(diǎn)是實(shí)現(xiàn)簡(jiǎn)單,可以使用消息隊(duì)列來(lái)削峰填谷。
但是也有3個(gè)問題需要考慮:
- 漏桶的大小,如果太大,可能給服務(wù)端帶來(lái)較大處理壓力,太小可能會(huì)有大量請(qǐng)求被丟棄。
- 漏桶給服務(wù)端的請(qǐng)求發(fā)送速率。
- 使用緩存請(qǐng)求的方式,會(huì)使請(qǐng)求響應(yīng)時(shí)間變長(zhǎng)。
漏桶大小和發(fā)送速率這2個(gè)值在項(xiàng)目上線初期都會(huì)根據(jù)測(cè)試結(jié)果選擇一個(gè)值,但是隨著架構(gòu)的改進(jìn)和集群的伸縮,這2個(gè)值也會(huì)隨之發(fā)生改變。
令牌桶算法
令牌桶算法就跟病人去醫(yī)院看病一樣,找醫(yī)生之前需要先掛號(hào),而醫(yī)院每天放的號(hào)是有限的。當(dāng)天的號(hào)用完了,第二天又會(huì)放一批號(hào)。
算法的基本思想就是周期性的執(zhí)行下面的流程:
客戶端在發(fā)送請(qǐng)求時(shí),都需要先從令牌桶中獲取令牌,如果取到了,就可以把請(qǐng)求發(fā)送給服務(wù)端,取不到令牌,就只能被拒絕或者走服務(wù)降級(jí)的邏輯。如下圖:
令牌桶算法解決了漏桶算法的問題,而且實(shí)現(xiàn)并不復(fù)雜,使用信號(hào)量就可以實(shí)現(xiàn)。在實(shí)際限流場(chǎng)景中使用最多,比如google的guava中就實(shí)現(xiàn)了令牌桶算法限流,感興趣可以研究一下。
分布式限流
如果在分布式系統(tǒng)場(chǎng)景下,上面介紹的4種限流算法是否還適用呢?
以令牌桶算法為例,假如在電商系統(tǒng)中客戶下了一筆訂單,如下圖:
如果我們把令牌桶單獨(dú)保存在一個(gè)地方(比如redis中)供整個(gè)分布式系統(tǒng)用,那客戶端在調(diào)用組合服務(wù),組合服務(wù)調(diào)用訂單、庫(kù)存和賬戶服務(wù)都需要跟令牌桶交互,交互次數(shù)明顯增加了很多。
有一種改進(jìn)就是客戶端調(diào)用組合服務(wù)之前首先獲取四個(gè)令牌,調(diào)用組合服務(wù)時(shí)減去一個(gè)令牌并且傳遞給組合服務(wù)三個(gè)令牌,組合服務(wù)調(diào)用下面三個(gè)服務(wù)時(shí)依次消耗一個(gè)令牌。
降級(jí)
降級(jí)是指當(dāng)自身服務(wù)壓力增大時(shí),采取一些手段,增強(qiáng)自身服務(wù)的處理能力,以保障服務(wù)的持續(xù)可用。比如,下線非核心服務(wù)以保證核心服務(wù)的穩(wěn)定、降低實(shí)時(shí)性、降低數(shù)據(jù)一致性。
總結(jié)

