服務(wù)熔斷牍帚、降級、限流乳蛾、異步RPC -- HyStrix

在今天暗赶,基于SOA的架構(gòu)已經(jīng)大行其道鄙币。伴隨著架構(gòu)的SOA化,相關(guān)聯(lián)的服務(wù)熔斷蹂随、降級十嘿、限流等思想,也在各種技術(shù)講座中頻繁出現(xiàn)岳锁。本文將結(jié)合Netflix開源的Hystrix框架绩衷,對這些思想做一個(gè)梳理。

背景
伴隨著業(yè)務(wù)復(fù)雜性的提高激率,系統(tǒng)的不斷拆分咳燕,一個(gè)面向用戶端的API,其內(nèi)部的RPC調(diào)用層層嵌套乒躺,調(diào)用鏈條可能會非常長招盲。這會造成以下幾個(gè)問題:

API接口可用性降低
引用Hystrix官方的一個(gè)例子,假設(shè)tomcat對外提供的一個(gè)application聪蘸,其內(nèi)部依賴了30個(gè)服務(wù),每個(gè)服務(wù)的可用性都很高表制,為99.99%健爬。那整個(gè)applicatiion的可用性就是:99.99%的30次方 = 99.7%,即0.3%的失敗率么介。

這也就意味著娜遵,每1億個(gè)請求,有30萬個(gè)失斎蓝獭设拟;按時(shí)間來算,就是每個(gè)月的故障時(shí)間超過2小時(shí)久脯。

系統(tǒng)被block
假設(shè)一個(gè)請求的調(diào)用鏈上面有10個(gè)服務(wù)纳胧,只要這10個(gè)服務(wù)中有1個(gè)超時(shí),就會導(dǎo)致這個(gè)請求超時(shí)帘撰。
更嚴(yán)重的跑慕,如果該請求的并發(fā)數(shù)很高,所有該請求在短時(shí)間內(nèi)都被block(等待超時(shí))摧找,tomcat的所有線程都block在此請求上核行,導(dǎo)致其他請求沒辦法及時(shí)響應(yīng)。

服務(wù)熔斷
為了解決上述問題蹬耘,服務(wù)熔斷的思想被提出來芝雪。類似現(xiàn)實(shí)世界中的“保險(xiǎn)絲“,當(dāng)某個(gè)異常條件被觸發(fā)综苔,直接熔斷整個(gè)服務(wù)惩系,而不是一直等到此服務(wù)超時(shí)位岔。
熔斷的觸發(fā)條件可以依據(jù)不同的場景有所不同,比如統(tǒng)計(jì)一個(gè)時(shí)間窗口內(nèi)失敗的調(diào)用次數(shù)蛆挫。

實(shí)現(xiàn)原理
實(shí)現(xiàn)原理講起來很簡單赃承,其實(shí)就是不讓客戶端“裸調(diào)“服務(wù)器的rpc接口,而是在客戶端包裝一層悴侵。就在這個(gè)包裝層里面瞧剖,實(shí)現(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)鍵點(diǎn):把一個(gè)RPC調(diào)用可免,封裝在一個(gè)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是被扔到一個(gè)線程中執(zhí)行的捉撮,也就是說,缺省是線程隔離策略妇垢。
還有一種策略就是不搞線程池巾遭,直接在調(diào)用者線程中執(zhí)行,也就是信號量的隔離策略闯估。
關(guān)于這2者的詳細(xì)區(qū)別灼舍,可以去參見官網(wǎng)。

熔斷的參數(shù)配置
Hystrix提供了如下的幾個(gè)關(guān)鍵參數(shù)涨薪,來對一個(gè)熔斷器進(jìn)行配置:

circuitBreaker.requestVolumeThreshold //滑動窗口的大小骑素,默認(rèn)為20
circuitBreaker.sleepWindowInMilliseconds //過多長時(shí)間,熔斷器再次檢測是否開啟刚夺,默認(rèn)為5000献丑,即5s鐘
circuitBreaker.errorThresholdPercentage //錯(cuò)誤率,默認(rèn)50%

3個(gè)參數(shù)放在一起侠姑,所表達(dá)的意思就是:
每當(dāng)20個(gè)請求中创橄,有50%失敗時(shí),熔斷器就會打開莽红,此時(shí)再調(diào)用此服務(wù)筐摘,將會直接返回失敗,不再調(diào)遠(yuǎn)程服務(wù)船老。直到5s鐘之后咖熟,重新檢測該觸發(fā)條件,判斷是否把熔斷器關(guān)閉柳畔,或者繼續(xù)打開馍管。

服務(wù)降級
有了熔斷,就得有降級薪韩。所謂降級确沸,就是當(dāng)某個(gè)服務(wù)熔斷之后捌锭,服務(wù)器將不再被調(diào)用,此時(shí)客戶端可以自己準(zhǔn)備一個(gè)本地的fallback回調(diào)罗捎,返回一個(gè)缺省值观谦。
這樣做,雖然服務(wù)水平下降桨菜,但好歹可用豁状,比直接掛掉要強(qiáng),當(dāng)然這也要看適合的業(yè)務(wù)場景倒得。

關(guān)于Hystrix中fallback的使用泻红,此處不詳述,參見官網(wǎng)霞掺。

服務(wù)限流
限流在日常生活中也很常見谊路,比如節(jié)假日你去一個(gè)旅游景點(diǎn),為了不把景點(diǎn)撐爆菩彬,管理部門通常會在外面設(shè)置攔截缠劝,限制景點(diǎn)的進(jìn)入人數(shù)(等有人出來之后,再放新的人進(jìn)去)骗灶。

對應(yīng)到計(jì)算機(jī)中惨恭,比如要搞活動,秒殺等矿卑,通常都會限流喉恋。

說到限流沃饶,有個(gè)關(guān)鍵問題就是:你根據(jù)什么策略進(jìn)行限制母廷??

比如在Hystrix中糊肤,如果是線程隔離琴昆,可以通過線程數(shù) + 隊(duì)列大小限制;如果是信號量隔離馆揉,可以設(shè)置最大并發(fā)請求數(shù)业舍。

另外一個(gè)常見的策略就是根據(jù)QPS限制,比如我知道我調(diào)用的一個(gè)db服務(wù)升酣,qps是3000舷暮,那如果不限制,超過3000噩茄,db就可能被打爆下面。這個(gè)時(shí)候,我可用在服務(wù)端做這個(gè)限流邏輯绩聘,也可以在客戶端做沥割。

現(xiàn)在一般成熟的RPC框架耗啦,都有參數(shù)直接設(shè)置這個(gè)。

還有一些場景下机杜,可用限制總數(shù):比如連接數(shù)帜讲,業(yè)務(wù)層面限制“庫存“總量等等。椒拗。

限流的技術(shù)原理 -令牌桶算法
關(guān)于限流的原理似将,相信很多人都聽說過令牌桶算法,Guava的RateLimiter也已經(jīng)有成熟做法陡叠,這個(gè)自己去搜索之玩郊。

此處想強(qiáng)調(diào)的是,令牌桶算法針對的是限制“速率“枉阵。至于其他限制策略译红,比如限制總數(shù),限制某個(gè)業(yè)務(wù)量的count值兴溜,則要具體業(yè)務(wù)場景具體分析侦厚。

異步RPC
異步RPC主要目的是提高并發(fā),比如你的接口拙徽,內(nèi)部調(diào)用了3個(gè)服務(wù)刨沦,時(shí)間分別為T1, T2, T3。如果是順序調(diào)用膘怕,則總時(shí)間是T1 + T2 + T3想诅;如果并發(fā)調(diào)用,總時(shí)間是Max(T1,T2,T3)岛心。

當(dāng)然来破,這里有1個(gè)前提條件,這3個(gè)調(diào)用直接忘古,互相不依賴徘禁。

同樣,一般成熟的RPC框架髓堪,本身都提高了異步化接口送朱,F(xiàn)uture或者Callback形式。

同樣干旁,Hystrix也提高了同步調(diào)用驶沼、異步調(diào)用方式,此處不再詳述争群。

總結(jié)
服務(wù)限流回怜、熔斷、降級祭阀、異步RPC是基于SOA的分布式系統(tǒng)中一些常見的基本策略鹉戚,并且這些策略現(xiàn)在都有成熟的開源框架支持鲜戒。用好這些策略,對整個(gè)系統(tǒng)的容錯(cuò)性抹凳、穩(wěn)定性有很大幫助遏餐。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市赢底,隨后出現(xiàn)的幾起案子失都,更是在濱河造成了極大的恐慌,老刑警劉巖幸冻,帶你破解...
    沈念sama閱讀 211,639評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件粹庞,死亡現(xiàn)場離奇詭異,居然都是意外死亡洽损,警方通過查閱死者的電腦和手機(jī)庞溜,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來碑定,“玉大人流码,你說我怎么就攤上這事⊙恿酰” “怎么了漫试?”我有些...
    開封第一講書人閱讀 157,221評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長碘赖。 經(jīng)常有香客問我驾荣,道長,這世上最難降的妖魔是什么普泡? 我笑而不...
    開封第一講書人閱讀 56,474評論 1 283
  • 正文 為了忘掉前任播掷,我火速辦了婚禮,結(jié)果婚禮上劫哼,老公的妹妹穿的比我還像新娘叮趴。我一直安慰自己割笙,他們只是感情好权烧,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,570評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著伤溉,像睡著了一般般码。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上乱顾,一...
    開封第一講書人閱讀 49,816評論 1 290
  • 那天板祝,我揣著相機(jī)與錄音,去河邊找鬼走净。 笑死券时,一個(gè)胖子當(dāng)著我的面吹牛孤里,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播橘洞,決...
    沈念sama閱讀 38,957評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼捌袜,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了炸枣?” 一聲冷哼從身側(cè)響起虏等,我...
    開封第一講書人閱讀 37,718評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎适肠,沒想到半個(gè)月后霍衫,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,176評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡侯养,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,511評論 2 327
  • 正文 我和宋清朗相戀三年敦跌,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片逛揩。...
    茶點(diǎn)故事閱讀 38,646評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡峰髓,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出息尺,到底是詐尸還是另有隱情携兵,我是刑警寧澤,帶...
    沈念sama閱讀 34,322評論 4 330
  • 正文 年R本政府宣布搂誉,位于F島的核電站徐紧,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏炭懊。R本人自食惡果不足惜并级,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,934評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望侮腹。 院中可真熱鬧嘲碧,春花似錦、人聲如沸父阻。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,755評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽加矛。三九已至履婉,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間斟览,已是汗流浹背毁腿。 一陣腳步聲響...
    開封第一講書人閱讀 31,987評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人已烤。 一個(gè)月前我還...
    沈念sama閱讀 46,358評論 2 360
  • 正文 我出身青樓鸠窗,卻偏偏與公主長得像,于是被迫代替她去往敵國和親胯究。 傳聞我的和親對象是個(gè)殘疾皇子塌鸯,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,514評論 2 348