https://windmt.com/2018/04/15/spring-cloud-4-hystrix/
服務(wù)雪崩的每個(gè)階段都可能由不同的原因造成素邪,比如造成 服務(wù)不可用的原因有:
1揭朝,硬件故障
2,程序Bug
3, 緩存擊穿
4欣除,用戶(hù)大量請(qǐng)求
硬件故障可能為硬件損壞造成的服務(wù)器主機(jī)宕機(jī)任斋,網(wǎng)絡(luò)硬件故障造成的服務(wù)提供ing者不可訪問(wèn)。
緩存擊穿一般發(fā)生在緩存應(yīng)用重啟,所有緩存被清空事废酷,以及短時(shí)間大量的緩存數(shù)據(jù)失效時(shí)瘟檩。大量的緩存不命中,使得大量的請(qǐng)求直擊后端澈蟆,造成服務(wù)提供者超負(fù)荷運(yùn)行墨辛,引起服務(wù)不可用。
在秒殺和大促開(kāi)始前趴俘,如果準(zhǔn)備不充分睹簇,用戶(hù)發(fā)起大量請(qǐng)求也會(huì)造成服務(wù)提供者的不可用。
而形成 重試加大流量的原因有:
用戶(hù)重試
代碼邏輯重試
在服務(wù)提供者不可用后寥闪,由于用戶(hù)忍受不了界面上長(zhǎng)時(shí)間的等待太惠,而不斷刷新頁(yè)面甚至提交表單,服務(wù)調(diào)用端的會(huì)存在大量服務(wù)異常后的重試邏輯疲憋。
這些重試都會(huì)進(jìn)一步加大請(qǐng)求流量
最后凿渊,服務(wù)調(diào)用者不可用產(chǎn)生的主要原因是:
同步等待造成的資源耗盡
當(dāng)服務(wù)調(diào)用者使用同步調(diào)用時(shí),會(huì)產(chǎn)生大量的等待線程占用系統(tǒng)資源缚柳。一旦系統(tǒng)資源被耗盡埃脏,服務(wù)調(diào)用者提供的服務(wù)也將處于不可用狀態(tài),于是服務(wù)雪崩效應(yīng)產(chǎn)生了秋忙。
應(yīng)對(duì)策略
針對(duì)造成服務(wù)雪崩的不同原因彩掐,可以使用不同的應(yīng)對(duì)策略
1.流量控制
2,改進(jìn)緩存模式
3灰追,服務(wù)自動(dòng)擴(kuò)容
4堵幽,服務(wù)調(diào)用者降級(jí)服務(wù)
流量控制 的具體措施包括:
網(wǎng)關(guān)限流
用戶(hù)交互限流
關(guān)閉重試
因?yàn)閚ginx 的高性能,目前一線互聯(lián)網(wǎng)公司大量采用Nginx+Lua 的網(wǎng)關(guān)進(jìn)行流量控制弹澎,由此而來(lái)的OpenResty 也越來(lái)越熱門(mén)
用戶(hù)交互限流的具體措施有: 1 采用加載動(dòng)畫(huà)谐檀,提高用戶(hù)的忍耐等待時(shí)間,2裁奇,提交按鈕添加強(qiáng)制等待時(shí)間機(jī)制
改進(jìn)緩存模式的措施包括:
緩存預(yù)加載
同步改為異步刷新
服務(wù)自動(dòng)擴(kuò)容的措施主要包括
AWS 的 auto scaling
服務(wù)調(diào)用者降級(jí)服務(wù)的措施包括:
資源隔離
對(duì)依賴(lài)服務(wù)分類(lèi)
不可用服務(wù)的代用快速失敗
資源隔離主要是對(duì)調(diào)用服務(wù)的線程池進(jìn)行隔離:
我們根據(jù)具體服務(wù)桐猬,將依賴(lài)服務(wù)分為:強(qiáng)依賴(lài)和弱依賴(lài),強(qiáng)依賴(lài)服務(wù)不可用會(huì)導(dǎo)致當(dāng)前業(yè)務(wù)終止刽肠,而弱依賴(lài)服務(wù)的不可用不會(huì)導(dǎo)致當(dāng)前業(yè)務(wù)的終止
不可用服務(wù)的調(diào)用快速失敗一般通過(guò) 超時(shí)機(jī)制溃肪,熔斷器 和熔斷后的降級(jí)方法來(lái)實(shí)現(xiàn)。
使用Hystrix預(yù)防服務(wù)雪崩
對(duì)于查詢(xún)操作音五,我們可以實(shí)現(xiàn)一個(gè)fallback方法惫撰,當(dāng)請(qǐng)求后端的服務(wù)出現(xiàn)異常的情況的時(shí)候,可以使用fallback 方法返回值躺涝。fallback 方法的返回值一般是設(shè)置的默認(rèn)值或者來(lái)自緩存厨钻。
資源隔離:
貨船為了進(jìn)行防止漏水和火災(zāi)的擴(kuò)散,會(huì)將貨倉(cāng)分隔為多個(gè),如下圖所示:
這種資源隔離減少風(fēng)險(xiǎn)的方式唄稱(chēng)為: Bulkheads(艙壁隔離模式)
hystrix 將同樣的模式運(yùn)用到了服務(wù)調(diào)用者上
在hystrix 中夯膀。主要通過(guò)線程池來(lái)實(shí)現(xiàn)資源隔離诗充。通常在使用的時(shí)候我們會(huì)根據(jù)調(diào)用的遠(yuǎn)程服務(wù)劃分出多個(gè)線程池。例如調(diào)用那個(gè)產(chǎn)品服務(wù)的Command 放入A線程池诱建,調(diào)用賬戶(hù)服務(wù)的Command 放入B 線程池 蝴蜓,這樣做的主要優(yōu)點(diǎn)是運(yùn)行環(huán)境被隔離開(kāi)了。這樣就算調(diào)用服務(wù)的代碼存在bug 或者由于其他的原因?qū)е伦约核炎影〉木€程池被耗盡時(shí)俺猿,不會(huì)對(duì)系統(tǒng)的其他的服務(wù)造成影響茎匠。
通過(guò)依賴(lài)服務(wù)的線程池隔離實(shí)現(xiàn),可以帶來(lái)如下優(yōu)勢(shì):
應(yīng)用自身得到完全的保護(hù)押袍,不會(huì)受不可控的依賴(lài)服務(wù)影響诵冒,即便給依賴(lài)服務(wù)分配的線程池填滿(mǎn),也不會(huì)影響自身的其余部分谊惭。
可以有效的降低介入新服務(wù)的風(fēng)險(xiǎn)汽馋。如果新服務(wù)接入后運(yùn)行不穩(wěn)定或存在問(wèn)題,完全不會(huì)影響到應(yīng)用其他的請(qǐng)求午笛。
當(dāng)依賴(lài)的服務(wù)從失效恢復(fù)正常后惭蟋,他的線程池會(huì)被清理并且馬上能夠恢復(fù)健康的服務(wù)苗桂,相比之下容器的級(jí)別的清理恢復(fù)速度要慢好多药磺。
當(dāng)依賴(lài)的服務(wù)出現(xiàn)配置錯(cuò)誤時(shí)候,線程池會(huì)快速的反映出此問(wèn)題(通過(guò)失敗次數(shù)煤伟,延遲癌佩,超時(shí),拒絕等指標(biāo)的增加情況)便锨。同時(shí)围辙,我們可以在不影響應(yīng)用功能的情況下通過(guò)實(shí)時(shí)的動(dòng)態(tài)屬性刷新(后續(xù)會(huì)通過(guò)Spring Cloud Config 與 Spring Cloud Bus 的聯(lián)合使用來(lái)介紹)來(lái)處理他
當(dāng)依賴(lài)的服務(wù)因?qū)崿F(xiàn)機(jī)制調(diào)整等原因造成其性能出現(xiàn)很大變化的時(shí)候,次數(shù)線程池的監(jiān)控指標(biāo)信息會(huì)反映出這樣的變化放案。同時(shí)姚建,我們也可以通過(guò)實(shí)時(shí)動(dòng)態(tài)刷新自身應(yīng)用對(duì)依賴(lài)服務(wù)的閥值進(jìn)行調(diào)整以適應(yīng)依賴(lài)方的改變。
除了上面通過(guò)線程池隔離服務(wù)發(fā)揮的優(yōu)點(diǎn)之外吱殉,每個(gè)專(zhuān)有的線程池都提供了內(nèi)置的并發(fā)實(shí)現(xiàn)掸冤。可以利用它為同步的依賴(lài)服務(wù)構(gòu)建異步的訪問(wèn)
總之友雳,通過(guò)對(duì)依賴(lài)服務(wù)實(shí)現(xiàn)線程池隔離稿湿,讓我們應(yīng)用更加健壯,不會(huì)因?yàn)閭€(gè)別依賴(lài)服務(wù)出現(xiàn)問(wèn)題而引起相關(guān)的異常押赊。同時(shí)饺藤,也使得我們的應(yīng)用變動(dòng)更加靈活,可以在不停止服務(wù)的情況下,配合動(dòng)態(tài)配置刷新實(shí)現(xiàn)性能配置上的調(diào)整涕俗。
雖然線程池隔離的方案帶來(lái)了好多好處罗丰,但是很多使用者可能胡擔(dān)心為為一個(gè)依賴(lài)服務(wù)都分配一個(gè)線程池是否會(huì)過(guò)多的增加系統(tǒng)的負(fù)載和開(kāi)銷(xiāo)。對(duì)于這一點(diǎn)咽袜,使用者不用過(guò)于擔(dān)心勉痴,因?yàn)檫@些顧慮也是大部分工程師們會(huì)考慮的秽晚,Netflix在設(shè)計(jì)Hystrix的時(shí)候,認(rèn)為線程池上的開(kāi)銷(xiāo)相對(duì)于隔離所帶來(lái)的好處是無(wú)法比擬的。同時(shí)寡壮,Netflix 也針對(duì)線程池的開(kāi)銷(xiāo)做了相關(guān)的測(cè)試。以證明和打消Hystrix 實(shí)現(xiàn)低性能影響的顧慮滤淳。
夏敏時(shí)候 Netflix Hystrix 官方提供的一個(gè)Hystrix 命令的性能監(jiān)控赏半,該命令以每秒60個(gè)請(qǐng)求的速度(QPS) 像一個(gè)單服務(wù)實(shí)例 進(jìn)行訪問(wèn),該服務(wù)實(shí)例每秒運(yùn)行的線程數(shù)峰值為350
斷路器模式
斷路器模式來(lái)源于 Martin Fowler的 CircuitnBreaker 一文蔽挠。 “斷路器””本身是一種開(kāi)關(guān)裝置住闯,用于在電路上保護(hù)線路過(guò)載。當(dāng)線路中有電器發(fā)生短路時(shí)澳淑,“斷路器” 能夠及時(shí)的切斷故障電路比原,防止發(fā)生過(guò)載,發(fā)熱杠巡,甚至起火等嚴(yán)重后果量窘。
在分布式架構(gòu)中,斷路器模式的作用也是類(lèi)似的氢拥,當(dāng)某個(gè)服務(wù)單元發(fā)生故障(類(lèi)似用電器發(fā)生短路)之后蚌铜,通過(guò)斷路器的故障監(jiān)控(類(lèi)似熔斷保險(xiǎn)絲),直接切斷原來(lái)的主邏輯調(diào)用嫩海。但是冬殃,在Hystrix 中的斷路器除了切斷主邏輯的功能之外,還有更復(fù)雜的邏輯叁怪,下面我們來(lái)看看他更為深層次的處理邏輯审葬。
斷路器開(kāi)關(guān)相互轉(zhuǎn)換的邏輯如下圖:
當(dāng)Hystrix Command 請(qǐng)求后端服務(wù)失敗數(shù)量超過(guò)一定的閥值,斷路器會(huì)切換到開(kāi)路狀態(tài)(Open)奕谭,這時(shí)候所有的請(qǐng)求會(huì)直接失敗而不會(huì)
發(fā)送到后端服務(wù)涣觉。
這個(gè)閥值涉及到三個(gè)重要的參數(shù): 快照時(shí)間窗,請(qǐng)求總數(shù)下限展箱,錯(cuò)誤百分比下限旨枯。這個(gè)參數(shù)的作用分別是:
快照時(shí)間窗: 斷路器確定是否打開(kāi)需要統(tǒng)計(jì)一些請(qǐng)求和錯(cuò)誤數(shù)據(jù),混驰,而統(tǒng)計(jì)的時(shí)間范圍就是快照的時(shí)間窗攀隔,默認(rèn)為最近的10秒
請(qǐng)求總數(shù)下限: 在快照時(shí)間窗內(nèi)皂贩,必須滿(mǎn)足請(qǐng)求總數(shù)下限才有資格進(jìn)行熔斷。默認(rèn)為20昆汹,意味著10秒內(nèi)明刷。如果該Hystrix Command 的調(diào)用此時(shí)不足20次,即時(shí)所有的請(qǐng)求都超時(shí)或者其他原因失敗满粗,斷路器都不會(huì)打開(kāi)辈末。
錯(cuò)誤百分比下限,當(dāng)請(qǐng)求總數(shù)在快照時(shí)間窗內(nèi)超過(guò)了下限映皆,比如發(fā)生了30次調(diào)用挤聘,如果在30次調(diào)用中,有16次發(fā)生了超時(shí)異常捅彻,也就是超過(guò)了50%的錯(cuò)誤百分比组去,在默認(rèn)設(shè)定50%下限的情況下,這時(shí)就會(huì)將 斷路器打開(kāi)步淹。
斷路器保持在開(kāi)路狀態(tài)下一段時(shí)間后(默認(rèn)5秒)从隆,自動(dòng)切換到半開(kāi)路狀態(tài)(HALF-OPEN).這時(shí)會(huì)判斷下一次請(qǐng)求的返回情況,如果請(qǐng)求成功缭裆,斷路器切回閉路狀態(tài)(CLOSED),否則重新切換到開(kāi)路狀態(tài)(OPEN)