Spring Cloud構(gòu)建微服務(wù)架構(gòu) 斷路器(服務(wù)器熔斷)

原文鏈接:http://blog.didispace.com/springcloud3/

在微服務(wù)架構(gòu)中伞芹,我們將系統(tǒng)拆分成了一個(gè)個(gè)的服務(wù)單元幌甘,各單元間通過(guò)服務(wù)注冊(cè)與訂閱的方式互相依賴(lài)。由于每個(gè)單元都在不同的進(jìn)程中運(yùn)行,依賴(lài)通過(guò)遠(yuǎn)程調(diào)用的方式執(zhí)行,這樣就有可能因?yàn)榫W(wǎng)絡(luò)原因或是依賴(lài)服務(wù)自身問(wèn)題出現(xiàn)調(diào)用故障或延遲,而這些問(wèn)題會(huì)直接導(dǎo)致調(diào)用方的對(duì)外服務(wù)也出現(xiàn)延遲峦朗,若此時(shí)調(diào)用方的請(qǐng)求不斷增加,最后就會(huì)出現(xiàn)因等待出現(xiàn)故障的依賴(lài)方響應(yīng)而形成任務(wù)積壓排龄,最終導(dǎo)致自身服務(wù)的癱瘓波势。

舉個(gè)例子,在一個(gè)電商網(wǎng)站中橄维,我們可能會(huì)將系統(tǒng)拆分成尺铣,用戶(hù)、訂單争舞、庫(kù)存凛忿、積分、評(píng)論等一系列的服務(wù)單元竞川。用戶(hù)創(chuàng)建一個(gè)訂單的時(shí)候店溢,在調(diào)用訂單服務(wù)創(chuàng)建訂單的時(shí)候,會(huì)向庫(kù)存服務(wù)來(lái)請(qǐng)求出貨(判斷是否有足夠庫(kù)存來(lái)出貨)委乌。此時(shí)若庫(kù)存服務(wù)因網(wǎng)絡(luò)原因無(wú)法被訪問(wèn)到床牧,導(dǎo)致創(chuàng)建訂單服務(wù)的線程進(jìn)入等待庫(kù)存申請(qǐng)服務(wù)的響應(yīng),在漫長(zhǎng)的等待之后用戶(hù)會(huì)因?yàn)檎?qǐng)求庫(kù)存失敗而得到創(chuàng)建訂單失敗的結(jié)果遭贸。如果在高并發(fā)情況之下戈咳,因這些等待線程在等待庫(kù)存服務(wù)的響應(yīng)而未能釋放,使得后續(xù)到來(lái)的創(chuàng)建訂單請(qǐng)求被阻塞,最終導(dǎo)致訂單服務(wù)也不可用著蛙。

在微服務(wù)架構(gòu)中删铃,存在著那么多的服務(wù)單元,若一個(gè)單元出現(xiàn)故障踏堡,就會(huì)因依賴(lài)關(guān)系形成故障蔓延猎唁,最終導(dǎo)致整個(gè)系統(tǒng)的癱瘓,這樣的架構(gòu)相較傳統(tǒng)架構(gòu)就更加的不穩(wěn)定顷蟆。為了解決這樣的問(wèn)題胖秒,因此產(chǎn)生了斷路器模式。

什么是斷路器

斷路器模式源于Martin Fowler的Circuit Breaker一文慕的。“斷路器”本身是一種開(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)絲)仪际,向調(diào)用方返回一個(gè)錯(cuò)誤響應(yīng),而不是長(zhǎng)時(shí)間的等待昵骤。這樣就不會(huì)使得線程因調(diào)用故障服務(wù)被長(zhǎng)時(shí)間占用不釋放树碱,避免了故障在分布式系統(tǒng)中的蔓延。

Netflix Hystrix

在Spring Cloud中使用了Hystrix?來(lái)實(shí)現(xiàn)斷路器的功能变秦。Hystrix是Netflix開(kāi)源的微服務(wù)框架套件之一成榜,該框架目標(biāo)在于通過(guò)控制那些訪問(wèn)遠(yuǎn)程系統(tǒng)、服務(wù)和第三方庫(kù)的節(jié)點(diǎn)蹦玫,從而對(duì)延遲和故障提供更強(qiáng)大的容錯(cuò)能力赎婚。Hystrix具備擁有回退機(jī)制和斷路器功能的線程和信號(hào)隔離,請(qǐng)求緩存和請(qǐng)求打包樱溉,以及監(jiān)控和配置等功能挣输。

下面我們來(lái)看看如何使用Hystrix。

準(zhǔn)備工作

在開(kāi)始加入斷路器之前饺窿,我們先拿之前構(gòu)建兩個(gè)微服務(wù)為基礎(chǔ)進(jìn)行下面的操作歧焦,主要使用下面幾個(gè)工程:

chapter9-1-1

eureka-server工程:服務(wù)注冊(cè)中心,端口1111

compute-service工程:服務(wù)單元,端口2222

chapter9-1-2

eureka-ribbon:通過(guò)ribbon實(shí)現(xiàn)的服務(wù)單元绢馍,依賴(lài)compute-service的服務(wù)向瓷,端口3333

eureka-feign:通過(guò)feign實(shí)現(xiàn)的服務(wù)單元,依賴(lài)compute-service的服務(wù)舰涌,端口3333

若您還沒(méi)有使用Spring Cloud的經(jīng)驗(yàn)猖任,可以先閱讀《服務(wù)注冊(cè)與發(fā)現(xiàn)》《服務(wù)消費(fèi)者》,對(duì)Spring Cloud構(gòu)建的微服務(wù)有一個(gè)初步的認(rèn)識(shí)瓷耙。

Ribbon中引入Hystrix

依次啟動(dòng)eureka-server朱躺、compute-service、eureka-ribbon工程

訪問(wèn)http://localhost:1111/可以看到注冊(cè)中心的狀態(tài)

訪問(wèn)http://localhost:3333/add搁痛,調(diào)用eureka-ribbon的服務(wù)长搀,該服務(wù)會(huì)去調(diào)用compute-service的服務(wù),計(jì)算出10+20的值鸡典,頁(yè)面顯示30

關(guān)閉compute-service服務(wù)源请,訪問(wèn)http://localhost:3333/add,我們獲得了下面的報(bào)錯(cuò)信息

Whitelabel Error Page

This application has no explicit mappingfor/error, so you are seeing this as a fallback.

Sat Jun 25 21:16:59 CST 2016

There was an unexpected error (type=Internal Server Error, status=500).

I/O error on GET requestfor"http://COMPUTE-SERVICE/add?a=10&b=20": Connection refused: connect; nested exception is java.net.ConnectException: Connection refused: connect

pom.xml中引入依賴(lài)hystrix依賴(lài)

org.springframework.cloud

spring-cloud-starter-hystrix

在eureka-ribbon的主類(lèi)RibbonApplication中使用@EnableCircuitBreaker注解開(kāi)啟斷路器功能:

@SpringBootApplication

@EnableDiscoveryClient

@EnableCircuitBreaker

publicclassRibbonApplication{

@Bean

@LoadBalanced

RestTemplaterestTemplate(){

returnnewRestTemplate();

}

publicstaticvoidmain(String[] args){

SpringApplication.run(RibbonApplication.class, args);

}

}

改造原來(lái)的服務(wù)消費(fèi)方式彻况,新增ComputeService類(lèi)谁尸,在使用ribbon消費(fèi)服務(wù)的函數(shù)上增加@HystrixCommand注解來(lái)指定回調(diào)方法。

@Service

publicclassComputeService{

@Autowired

? ? RestTemplate restTemplate;

@HystrixCommand(fallbackMethod ="addServiceFallback")

publicStringaddService(){

returnrestTemplate.getForEntity("http://COMPUTE-SERVICE/add?a=10&b=20", String.class).getBody();

? ? }

publicStringaddServiceFallback(){

return"error";

? ? }

}

提供rest接口的Controller改為調(diào)用ComputeService的addService

@RestController

publicclassConsumerController{

@Autowired

privateComputeService computeService;

@RequestMapping(value ="/add", method = RequestMethod.GET)

publicStringadd(){

returncomputeService.addService();

? ? }

}

驗(yàn)證斷路器的回調(diào)

依次啟動(dòng)eureka-server纽甘、compute-service良蛮、eureka-ribbon工程

訪問(wèn)http://localhost:1111/可以看到注冊(cè)中心的狀態(tài)

訪問(wèn)http://localhost:3333/add,頁(yè)面顯示:30

關(guān)閉compute-service服務(wù)后再訪問(wèn)http://localhost:3333/add悍赢,頁(yè)面顯示:error

Feign使用Hystrix

注意這里說(shuō)的是“使用”决瞳,沒(méi)有錯(cuò),我們不需要在Feigh工程中引入Hystix左权,F(xiàn)eign中已經(jīng)依賴(lài)了Hystrix瞒斩,我們可以在未做任何改造前,嘗試下面你的操作:

依次啟動(dòng)eureka-server涮总、compute-service胸囱、eureka-feign工程

訪問(wèn)http://localhost:1111/可以看到注冊(cè)中心的狀態(tài)

訪問(wèn)http://localhost:3333/add,調(diào)用eureka-feign的服務(wù)瀑梗,該服務(wù)會(huì)去調(diào)用compute-service的服務(wù)烹笔,計(jì)算出10+20的值,頁(yè)面顯示30

關(guān)閉compute-service服務(wù)抛丽,訪問(wèn)http://localhost:3333/add谤职,我們獲得了下面的報(bào)錯(cuò)信息

Whitelabel Error Page

This application has no explicit mappingfor/error, so you are seeing this as a fallback.

Sat Jun 25 22:10:05 CST 2016

There was an unexpected error (type=Internal Server Error, status=500).

add timed-out and no fallback available.

如果您夠仔細(xì),會(huì)發(fā)現(xiàn)與在ribbon中的報(bào)錯(cuò)是不同的亿鲜,看到add timed-out and no fallback available這句允蜈,或許您已經(jīng)猜到什么冤吨,看看我們的控制臺(tái),可以看到報(bào)錯(cuò)信息來(lái)自hystrix-core-1.5.2.jar饶套,所以在這個(gè)工程中漩蟆,我們要學(xué)習(xí)的就是如何使用Feign中集成的Hystrix。

使用@FeignClient注解中的fallback屬性指定回調(diào)類(lèi)

@FeignClient(value ="compute-service", fallback = ComputeClientHystrix.class)

publicinterfaceComputeClient{

@RequestMapping(method = RequestMethod.GET, value ="/add")

Integeradd(@RequestParam(value ="a")Integer a, @RequestParam(value ="b")Integer b);

}

創(chuàng)建回調(diào)類(lèi)ComputeClientHystrix妓蛮,實(shí)現(xiàn)@FeignClient的接口怠李,此時(shí)實(shí)現(xiàn)的方法就是對(duì)應(yīng)@FeignClient接口中映射的fallback函數(shù)。

@Component

publicclassComputeClientHystriximplementsComputeClient{

@Override

publicIntegeradd(@RequestParam(value ="a")Integer a, @RequestParam(value ="b")Integer b){

return-9999;

? ? }

}

再用之前的方法驗(yàn)證一下蛤克,是否在compute-service服務(wù)不可用的情況下捺癞,頁(yè)面返回了-9999。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末构挤,一起剝皮案震驚了整個(gè)濱河市髓介,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌筋现,老刑警劉巖版保,帶你破解...
    沈念sama閱讀 216,919評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異夫否,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)叫胁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,567評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)凰慈,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人驼鹅,你說(shuō)我怎么就攤上這事微谓。” “怎么了输钩?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,316評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵豺型,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我买乃,道長(zhǎng)姻氨,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,294評(píng)論 1 292
  • 正文 為了忘掉前任剪验,我火速辦了婚禮肴焊,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘功戚。我一直安慰自己娶眷,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,318評(píng)論 6 390
  • 文/花漫 我一把揭開(kāi)白布啸臀。 她就那樣靜靜地躺著届宠,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上豌注,一...
    開(kāi)封第一講書(shū)人閱讀 51,245評(píng)論 1 299
  • 那天伤塌,我揣著相機(jī)與錄音,去河邊找鬼幌羞。 笑死寸谜,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的属桦。 我是一名探鬼主播熊痴,決...
    沈念sama閱讀 40,120評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼聂宾!你這毒婦竟也來(lái)了果善?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 38,964評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤系谐,失蹤者是張志新(化名)和其女友劉穎巾陕,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體纪他,經(jīng)...
    沈念sama閱讀 45,376評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡鄙煤,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,592評(píng)論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了茶袒。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片梯刚。...
    茶點(diǎn)故事閱讀 39,764評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖薪寓,靈堂內(nèi)的尸體忽然破棺而出亡资,到底是詐尸還是另有隱情,我是刑警寧澤向叉,帶...
    沈念sama閱讀 35,460評(píng)論 5 344
  • 正文 年R本政府宣布锥腻,位于F島的核電站,受9級(jí)特大地震影響母谎,放射性物質(zhì)發(fā)生泄漏瘦黑。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,070評(píng)論 3 327
  • 文/蒙蒙 一奇唤、第九天 我趴在偏房一處隱蔽的房頂上張望供璧。 院中可真熱鬧,春花似錦冻记、人聲如沸睡毒。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,697評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)演顾。三九已至供搀,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間钠至,已是汗流浹背葛虐。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,846評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留棉钧,地道東北人屿脐。 一個(gè)月前我還...
    沈念sama閱讀 47,819評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像宪卿,于是被迫代替她去往敵國(guó)和親的诵。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,665評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容