在分布式服務(wù)環(huán)境下,服務(wù)之間的調(diào)用關(guān)系變得錯(cuò)綜復(fù)雜,你是否擔(dān)心依賴的服務(wù)延遲導(dǎo)致自己的服務(wù)也被拖跨呢?是否在苦苦思考如何優(yōu)雅的對(duì)依賴服務(wù)進(jìn)行異步調(diào)用呢?是否希望當(dāng)流量高峰時(shí)自動(dòng)進(jìn)行服務(wù)降級(jí)避免把自己線程耗盡而宕機(jī)?以上的問題,Hystrix能有效的解決。 什么是Hystrix 【注*】 Hystrix由Netflix于2011年創(chuàng)立的項(xiàng)目,最初是用于解決系統(tǒng)快速恢復(fù)的需求,其特性能保證在分布式服務(wù)中,防止服務(wù)失敗引起的級(jí)聯(lián)失敗,項(xiàng)目的熔斷機(jī)制能夠使依賴服務(wù)的調(diào)用快速失敗并且自動(dòng)恢復(fù),有效避免對(duì)失敗的服務(wù)進(jìn)行請(qǐng)求。同時(shí)對(duì)每個(gè)接口進(jìn)行線程池隔離(或按信號(hào)量隔離),避免因?yàn)楦叻辶髁炕蚍?wù)延遲導(dǎo)致線程耗盡而宕機(jī)。 【注*】 Hystrix入門介紹 Hystrix使用HystrixCommand和HystrixObservableCommand進(jìn)行對(duì)調(diào)用接口的封裝,從而使接口的調(diào)用自動(dòng)實(shí)現(xiàn)了線程隔離以及調(diào)用熔斷機(jī)制,通過執(zhí)行execute() 或者queue() 就能完成接口的同步或者異步調(diào)用。使用上手相當(dāng)輕松,那么我們就先以一個(gè)簡(jiǎn)單程序來認(rèn)識(shí)Hystrix: a) 項(xiàng)目加入Hystrix依賴
b) 創(chuàng)建一個(gè)用來被調(diào)用的方法, HelloWorldService
c) 創(chuàng)建一個(gè)使用HystrixCommand包裝的調(diào)用, HelloWorldInvoker
d) 進(jìn)行調(diào)用測(cè)試
Hystrix核心框架(HystrixCommand) HystrixCommand是框架的流程核心類,主要承擔(dān)封裝接口的調(diào)用執(zhí)行,將接口調(diào)用進(jìn)行命令分組,調(diào)用執(zhí)行進(jìn)行線程池隔離,請(qǐng)求的結(jié)果緩存命中,判斷熔斷,以及執(zhí)行錯(cuò)誤或熔斷后的結(jié)果FallBack機(jī)制流程,主要工作流程如下圖: 【注*】 4.1 HystrixCommand創(chuàng)建 HystrixCommand創(chuàng)建需要兩個(gè)必填參數(shù):HystrixCommandGroupKey和HystrixThreadPoolKey,HystrixCommandGroupKey用于進(jìn)行command分組,便于調(diào)用統(tǒng)計(jì)。HystrixThreadPoolKey用于線程池隔離,相同的線程池key的接口調(diào)用,將會(huì)使用相同的線程池,線程池大小默認(rèn)為10個(gè)線程,其余參數(shù)將會(huì)一并初始化。 4.2 HystrixCommand執(zhí)行 分別可使用execute(),queue(),observe(),toObservable()完成接口調(diào)用并包裝上述工作全流程, 四種執(zhí)行方式區(qū)別如下: a) execute:command執(zhí)行后進(jìn)行同步等待,直到結(jié)果返回 b) queue:command執(zhí)行后返回一個(gè)Future對(duì)象,F(xiàn)uture對(duì)象可以進(jìn)行異步的結(jié)果獲取 c) observe:command立即執(zhí)行,進(jìn)行接口調(diào)用后并返回observable,外部subscriber進(jìn)行數(shù)據(jù)讀取 d) toObservable:command不會(huì)立即執(zhí)行,接口調(diào)用僅當(dāng)有外部subscriber進(jìn)行訂閱后,接口才會(huì)被調(diào)用 前三種執(zhí)行方式都是toObservable的變種,command底層均是執(zhí)行toObservable方法得到一個(gè)Observable對(duì)象,然后該對(duì)象被訂閱的Subscriber進(jìn)行結(jié)果獲取。過程如下: 【注*】 Hystrix核心框架(HystrixCircuitBreaker) 5.1 熔斷器HystrixCircuitBreaker,是保證調(diào)用接口延遲或失敗情況下自動(dòng)熔斷,保證服務(wù)不被外部調(diào)用的失敗而拖跨。熔斷器和每個(gè)HystrixCommand綁定,為每個(gè)獨(dú)立的command進(jìn)行失敗計(jì)數(shù)和熔斷狀態(tài)控制。在創(chuàng)建command時(shí)對(duì)熔斷器進(jìn)行初始化
5.2 HystrixCircuitBreaker 通過HealthCountsStream維護(hù)一個(gè)command調(diào)用的健康計(jì)數(shù)器,如果計(jì)數(shù)器的線程堆積數(shù)大于允許的闕值或者調(diào)用失敗比例大于允許的百分比,則進(jìn)行熔斷處理,后續(xù)接口調(diào)用均會(huì)被短路并降級(jí)調(diào)用fallBack()返回。
5.3 HystrixCircuitBreaker將在熔斷后的一段時(shí)間內(nèi),允許部分請(qǐng)求進(jìn)行接口調(diào)用,若返回接口正確,則熔斷器將關(guān)閉,服務(wù)進(jìn)行正常請(qǐng)求,若此時(shí)接口調(diào)用仍舊失敗,則熔斷器保持熔斷,并重新進(jìn)行半熔斷狀態(tài)倒計(jì)時(shí)。 Hystrix核心框架(RequestCache) 接口調(diào)用中,如果不是高頻次修改的數(shù)據(jù)查詢結(jié)果,可以使用請(qǐng)求緩存來減少服務(wù)調(diào)用的網(wǎng)絡(luò)開銷,Hystrix會(huì)基于調(diào)用的key進(jìn)行結(jié)果命中,當(dāng)能匹配到結(jié)果是則直接返回結(jié)果而避免進(jìn)行接口調(diào)用。 a) 請(qǐng)求緩存是基于command中的getCacheKey()方法判斷是否是相同請(qǐng)求,所以需重寫該方法 b) 確保在調(diào)用之前開啟HystrixRequestContext,可以使用統(tǒng)一的攔截器來進(jìn)行攔截開啟。
Hystrix核心框架(FallBack) 當(dāng)接口調(diào)用超時(shí)或者直接出現(xiàn)異常,框架將對(duì)接口調(diào)用進(jìn)行降級(jí)處理,調(diào)用fallBack進(jìn)行結(jié)果返回。接口調(diào)用的降級(jí)只需要在HystrixCommand中重寫getFallBack()方法,方法同接口調(diào)用一樣的返回,用于直接書寫接口返回,或者在fallBack中繼續(xù)調(diào)用HystrixCommand進(jìn)行接口的降級(jí)調(diào)用
總結(jié) Hystrix對(duì)于接口調(diào)用具有很好的保護(hù),能在多服務(wù)依賴的分布式系統(tǒng)中,有效的提供應(yīng)用的可用性,并且對(duì)失敗應(yīng)用進(jìn)行熔斷和恢復(fù)檢查,讓應(yīng)用在復(fù)雜的環(huán)境中也能各種穩(wěn)。
注* : 圖片轉(zhuǎn)載于Hystrix的項(xiàng)目wiki, https://github.com/Netflix/Hystrix/wiki |
|