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