服务熔断、降级、限流、异步RPC -- HyStrix
本人新書出版,對技術(shù)感興趣的朋友請關(guān)注:
https://mp.weixin.qq.com/s/uq2cw2Lgf-s4nPHJ4WH4aw
在今天,基于SOA的架構(gòu)已經(jīng)大行其道。伴隨著架構(gòu)的SOA化,相關(guān)聯(lián)的服務(wù)熔斷、降級、限流等思想,也在各種技術(shù)講座中頻繁出現(xiàn)。本文將結(jié)合Netflix開源的Hystrix框架,對這些思想做一個梳理。
背景
伴隨著業(yè)務(wù)復(fù)雜性的提高,系統(tǒng)的不斷拆分,一個面向用戶端的API,其內(nèi)部的RPC調(diào)用層層嵌套,調(diào)用鏈條可能會非常長。這會造成以下幾個問題:
API接口可用性降低
引用Hystrix官方的一個例子,假設(shè)tomcat對外提供的一個application,其內(nèi)部依賴了30個服務(wù),每個服務(wù)的可用性都很高,為99.99%。那整個applicatiion的可用性就是:99.99%的30次方 = 99.7%,即0.3%的失敗率。
這也就意味著,每1億個請求,有30萬個失敗;按時間來算,就是每個月的故障時間超過2小時。
系統(tǒng)被block
假設(shè)一個請求的調(diào)用鏈上面有10個服務(wù),只要這10個服務(wù)中有1個超時,就會導(dǎo)致這個請求超時。
更嚴(yán)重的,如果該請求的并發(fā)數(shù)很高,所有該請求在短時間內(nèi)都被block(等待超時),tomcat的所有線程都block在此請求上,導(dǎo)致其他請求沒辦法及時響應(yīng)。
服務(wù)熔斷
為了解決上述問題,服務(wù)熔斷的思想被提出來。類似現(xiàn)實世界中的“保險絲“,當(dāng)某個異常條件被觸發(fā),直接熔斷整個服務(wù),而不是一直等到此服務(wù)超時。
熔斷的觸發(fā)條件可以依據(jù)不同的場景有所不同,比如統(tǒng)計一個時間窗口內(nèi)失敗的調(diào)用次數(shù)。
實現(xiàn)原理
實現(xiàn)原理講起來很簡單,其實就是不讓客戶端“裸調(diào)“服務(wù)器的rpc接口,而是在客戶端包裝一層。就在這個包裝層里面,實現(xiàn)熔斷邏輯。
拿Hystrix的helloword舉例:
public class CommandHelloWorld extends HystrixCommand<String> {
? ? private final String name;
? ? public CommandHelloWorld(String name) {
? ? ? ? super(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"));
? ? ? ? this.name = name;
? ? }
? ? @Override
? ? protected String run() {
? ? ? ? //關(guān)鍵點:把一個RPC調(diào)用,封裝在一個HystrixCommand里面
? ? ? ? return "Hello " + name + "!";
? ? }
}
//客戶端調(diào)用:以前是直接調(diào)用遠(yuǎn)端RPC接口,現(xiàn)在是把RPC接口封裝到HystrixCommand里面,它內(nèi)部完成熔斷邏輯
String s = new CommandHelloWorld("World").execute();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
隔離策略: 線程 vs 信號量
缺省的,上面的HystrixCommand是被扔到一個線程中執(zhí)行的,也就是說,缺省是線程隔離策略。
還有一種策略就是不搞線程池,直接在調(diào)用者線程中執(zhí)行,也就是信號量的隔離策略。
關(guān)于這2者的詳細(xì)區(qū)別,可以去參見官網(wǎng)。
熔斷的參數(shù)配置
Hystrix提供了如下的幾個關(guān)鍵參數(shù),來對一個熔斷器進行配置:
circuitBreaker.requestVolumeThreshold //滑動窗口的大小,默認(rèn)為20
circuitBreaker.sleepWindowInMilliseconds //過多長時間,熔斷器再次檢測是否開啟,默認(rèn)為5000,即5s鐘
circuitBreaker.errorThresholdPercentage //錯誤率,默認(rèn)50%
3個參數(shù)放在一起,所表達(dá)的意思就是:
每當(dāng)20個請求中,有50%失敗時,熔斷器就會打開,此時再調(diào)用此服務(wù),將會直接返回失敗,不再調(diào)遠(yuǎn)程服務(wù)。直到5s鐘之后,重新檢測該觸發(fā)條件,判斷是否把熔斷器關(guān)閉,或者繼續(xù)打開。
服務(wù)降級
有了熔斷,就得有降級。所謂降級,就是當(dāng)某個服務(wù)熔斷之后,服務(wù)器將不再被調(diào)用,此時客戶端可以自己準(zhǔn)備一個本地的fallback回調(diào),返回一個缺省值。
這樣做,雖然服務(wù)水平下降,但好歹可用,比直接掛掉要強,當(dāng)然這也要看適合的業(yè)務(wù)場景。
關(guān)于Hystrix中fallback的使用,此處不詳述,參見官網(wǎng)。
服務(wù)限流
限流在日常生活中也很常見,比如節(jié)假日你去一個旅游景點,為了不把景點撐爆,管理部門通常會在外面設(shè)置攔截,限制景點的進入人數(shù)(等有人出來之后,再放新的人進去)。
對應(yīng)到計算機中,比如要搞活動,秒殺等,通常都會限流。
說到限流,有個關(guān)鍵問題就是:你根據(jù)什么策略進行限制??
比如在Hystrix中,如果是線程隔離,可以通過線程數(shù) + 隊列大小限制;如果是信號量隔離,可以設(shè)置最大并發(fā)請求數(shù)。
另外一個常見的策略就是根據(jù)QPS限制,比如我知道我調(diào)用的一個db服務(wù),qps是3000,那如果不限制,超過3000,db就可能被打爆。這個時候,我可用在服務(wù)端做這個限流邏輯,也可以在客戶端做。
現(xiàn)在一般成熟的RPC框架,都有參數(shù)直接設(shè)置這個。
還有一些場景下,可用限制總數(shù):比如連接數(shù),業(yè)務(wù)層面限制“庫存“總量等等。。
限流的技術(shù)原理 -令牌桶算法
關(guān)于限流的原理,相信很多人都聽說過令牌桶算法,Guava的RateLimiter也已經(jīng)有成熟做法,這個自己去搜索之。
此處想強調(diào)的是,令牌桶算法針對的是限制“速率“。至于其他限制策略,比如限制總數(shù),限制某個業(yè)務(wù)量的count值,則要具體業(yè)務(wù)場景具體分析。
異步RPC
異步RPC主要目的是提高并發(fā),比如你的接口,內(nèi)部調(diào)用了3個服務(wù),時間分別為T1, T2, T3。如果是順序調(diào)用,則總時間是T1 + T2 + T3;如果并發(fā)調(diào)用,總時間是Max(T1,T2,T3)。
當(dāng)然,這里有1個前提條件,這3個調(diào)用直接,互相不依賴。
同樣,一般成熟的RPC框架,本身都提高了異步化接口,Future或者Callback形式。
同樣,Hystrix也提高了同步調(diào)用、異步調(diào)用方式,此處不再詳述。
總結(jié)
服務(wù)限流、熔斷、降級、異步RPC是基于SOA的分布式系統(tǒng)中一些常見的基本策略,并且這些策略現(xiàn)在都有成熟的開源框架支持。用好這些策略,對整個系統(tǒng)的容錯性、穩(wěn)定性有很大幫助。
#后話
有興趣朋友可以關(guān)注公眾號“架構(gòu)之道與術(shù)”, 獲取最新文章和進一步討論。
---------------------?
作者:travi?
來源:CSDN?
原文:https://blog.csdn.net/chunlongyu/article/details/53259014?
版權(quán)聲明:本文為博主原創(chuàng)文章,轉(zhuǎn)載請附上博文鏈接!
總結(jié)
以上是生活随笔為你收集整理的服务熔断、降级、限流、异步RPC -- HyStrix的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: “我是技术总监,你干嘛总问我技术细节?”
- 下一篇: 电磁炉不加热咋回事(电磁炉不加热别的都正