創(chuàng)建流程
構(gòu)建HystrixCommand或者HystrixObservableCommand對象
- *使用Hystrix的第一步是創(chuàng)建一個HystrixCommand或者HystrixObservableCommand對象來表示你需要發(fā)給依賴服務(wù)的請求。
若只期望依賴服務(wù)每次返回單一的回應(yīng)芍躏,按如下方式構(gòu)造一個HystrixCommand即可:
HystrixCommand command = new HystrixCommand(arg1, arg2);
復(fù)制代碼
若期望依賴服務(wù)返回一個Observable,并應(yīng)用『Observer』模式監(jiān)聽依賴服務(wù)的回應(yīng)袭灯,可按如下方式構(gòu)造一個HystrixObservableCommand:
HystrixObservableCommand command = new HystrixObservableCommand(arg1, arg2);
復(fù)制代碼
執(zhí)行命令
Hystrix 命令提供四種方式(HystrixCommand支持所有四種方式雀扶,而HystrixObservableCommand僅支持后兩種方式)來執(zhí)行你包裝的請求:
- execute()—— 阻塞,當依賴服務(wù)響應(yīng)(或者拋出異常/超時)時,返回結(jié)果
- queue()—— 返回Future對象尊沸,通過該對象異步得到返回結(jié)果
- observe()—— 返回Observable對象俊犯,立即發(fā)出請求妇多,在依賴服務(wù)響應(yīng)(或者拋出異常/超時)時,通過注冊的Subscriber得到返回結(jié)果
- *toObservable()—— 返回Observable對象瘫析,但只有在訂閱該對象時砌梆,才會發(fā)出請求,然后在依賴服務(wù)響應(yīng)(或者拋出異常/超時)時贬循,通過注冊的Subscriber得到返回結(jié)果
K value = command.execute();
Future fValue = command.queue();
Observable ohValue = command.observe();
Observable ocValue = command.toObservable();
復(fù)制代碼
內(nèi)部實現(xiàn)中
- execute()是同步調(diào)用咸包,內(nèi)部會調(diào)用queue().get()方法。
- queue()內(nèi)部會調(diào)用toObservable().toBlocking().toFuture()杖虾。
HystrixCommand內(nèi)部均通過一個Observable的實現(xiàn)來執(zhí)行請求烂瘫,即使這些命令本來是用來執(zhí)行同步返回回應(yīng)這樣的簡單邏輯。
1. 結(jié)果是否有緩存
如果請求結(jié)果緩存這個特性被啟用奇适,并且緩存命中坟比,則緩存的回應(yīng)會立即通過一個Observable對象的形式返回。
2. 請求線路是否是開路
- 當執(zhí)行一個命令時嚷往,Hystrix 會先檢查熔斷器狀態(tài)葛账,確定請求線路是否是開路
- *如果請求線路是開路,Hystrix將不會執(zhí)行這個命令皮仁,而是直接使用『失敗回退邏輯』fallback
3. 線程池/請求隊列/信號量占滿時會發(fā)生什么
如果和當前需要執(zhí)行的命令相關(guān)聯(lián)的線程池和請求隊列(或者信號量籍琳,如果不使用線程池),Hystrix 將不會執(zhí)行這個命令贷祈,而是直接使用『失敗回退邏輯』
使用HystrixObservableCommand.construct()還是HystrixCommand.run()
Hystrix將根據(jù)你使用類的不同趋急,內(nèi)部使用不同的方式來請求依賴服務(wù):
- HystrixCommand.run()—— 返回回應(yīng)或者拋出異常
- *HystrixObservableCommand.construct()—— 返回Observable對象,并在回應(yīng)到達時通知 observers势誊,或者回調(diào)onError方法通知出現(xiàn)異常
若run()或者construct()方法耗時超過了給命令設(shè)置的超時閾值呜达,執(zhí)行請求的線程將拋出TimeoutException( 若命令本身并不在其調(diào)用線程內(nèi)執(zhí)行,則單獨的定時器線程會拋出該異常)粟耻。
在這種情況下查近,Hystrix將會執(zhí)行失敗回退邏輯,并且會忽略最終(若執(zhí)行命令的線程沒有被中斷)返回的回應(yīng)挤忙。
若命令本身并不拋出異常霜威,并正常返回回應(yīng),Hystrix在添加一些日志和監(jiān)控數(shù)據(jù)采集之后饭玲,直接返回回應(yīng)侥祭。
- Hystrix 在使用run()方法時,Hystrix內(nèi)部還是會生成一個Observable對象,并返回單個請求矮冬,產(chǎn)生一個onCompleted通知谈宛;
- *而在 Hystrix 使用construct()時,會直接返回由construct()產(chǎn)生的Observable對象
計算線路健康度
Hystrix會將請求成功胎署,失敗吆录,被拒絕或超時信息報告給熔斷器,熔斷器維護一些用于統(tǒng)計數(shù)據(jù)用的計數(shù)器琼牧。
這些計數(shù)器產(chǎn)生的統(tǒng)計數(shù)據(jù)使得熔斷器在特定的時刻恢筝,能短路某個依賴服務(wù)的后續(xù)請求,直到恢復(fù)期結(jié)束巨坊,若恢復(fù)期結(jié)束根據(jù)統(tǒng)計數(shù)據(jù)熔斷器判定線路仍然未恢復(fù)健康撬槽,熔斷器會再次關(guān)閉線路。
失敗回退邏輯
當命令執(zhí)行失敗時趾撵,Hystrix 將會執(zhí)行失敗回退邏輯侄柔,失敗原因可能是:
- construct()或run()方法拋出異常( HystrixBadRequestException除外)
- 當線路是開路,導(dǎo)致命令被短路時
- 當命令對應(yīng)的線程池或信號量被占滿
- 執(zhí)行操作超時占调!
回退具體介紹
- 失敗回退邏輯包含了通用的回應(yīng)信息暂题,這些回應(yīng)從內(nèi)存緩存中或者其他固定邏輯中得到,而不應(yīng)有任何的網(wǎng)絡(luò)依賴究珊。
- 如果一定要在失敗回退邏輯中包含網(wǎng)絡(luò)請求薪者,必須將這些網(wǎng)絡(luò)請求包裝在另一個HystrixCommand或HystrixObservableCommand中。
- 當使用HystrixCommand時剿涮,通過實現(xiàn)HystrixCommand.getFallback()返回失敗回退時的回應(yīng)言津。
- 當使用HystrixObservableCommand時,通過實現(xiàn)HystrixObservableCommand.resumeWithFallback()返回 Observable 對象來通知 observers 失敗回退時的回應(yīng)幔虏。
-
若失敗回退方法返回回應(yīng)纺念,Hystrix會將這個回應(yīng)返回給命令的調(diào)用者贝椿。
- 若Hystrix內(nèi)部調(diào)用HystrixCommand.getFallback()時想括,會產(chǎn)生一個Observable對象,并包裝用戶實現(xiàn)的getFallback()方法返回的回應(yīng)烙博;
- 若 Hystrix內(nèi)部調(diào)用HystrixObservableCommand.resumeWithFallback()時瑟蜈,會將用戶實現(xiàn)的resumeWithFallback()返回的Observable對象直接返回。
- 若你沒有實現(xiàn)失敗回退方法渣窜,或者失敗回退方法拋出異常铺根,Hystrix 內(nèi)部還是會生成一個 Observable對象,但它不會產(chǎn)生任何回應(yīng)乔宿,并通過onError通知立即中止請求。
- Hystrix默認會通過onError通知調(diào)用者發(fā)生了何種異常。你需要盡量避免失敗回退方法執(zhí)行失敗嘁锯,保持該方法盡可能的簡單不易出錯。
-
若失敗回退方法執(zhí)行失敗臣缀,或者用戶未提供失敗回退方法,Hystrix會根據(jù)調(diào)用執(zhí)行命令的方法的不同而產(chǎn)生不同的行為:
- execute()—— 拋出異常
- queue()—— 成功返回Future對象泻帮,但其get()方法被調(diào)用時精置,會拋出異常
- observe()—— 返回Observable對象,當你訂閱它的時候锣杂,會立即調(diào)用 subscriber 的onError方法中止請求
- *toObservable()—— 返回Observable對象脂倦,當你訂閱它的時候,會立即調(diào)用 subscriber 的onError方法中止請求
返回正吃回應(yīng)
若命令成功被執(zhí)行赖阻,Hystrix將回應(yīng)返回給調(diào)用方,或者通過Observable的形式返回踱蠢。根據(jù)上述調(diào)用命令方式的不同(如第2條所示)政供,Observable對象會進行一些轉(zhuǎn)換:
[圖片上傳失敗...(image-a834c5-1691543452740)]
Observable對象的轉(zhuǎn)化
- execute()—— 產(chǎn)生一個Future對象,行為同.queue()產(chǎn)生的Future對象一樣朽基,接著調(diào)用其get()方法布隔,生成由內(nèi)部產(chǎn)生的Observable對象返回的回應(yīng)
- queue()—— 將內(nèi)部產(chǎn)生的Observable對象轉(zhuǎn)換(Decorator模式)成BlockingObservable對象,以產(chǎn)生并返回Future對象
- observe()—— 產(chǎn)生Observable對象后稼虎,立即訂閱(ReplaySubject)以使命令得以執(zhí)行(異步)衅檀,返回該Observable對象,當你調(diào)用其subscribe方法時霎俩,重放產(chǎn)生的回應(yīng)信息和通知給用戶提供的訂閱者
- toObservable()—— 返回Observable對象哀军,你必須調(diào)用其subscribe方法,以使命令得以執(zhí)行打却。
熔斷器
下圖展示了HystrixCommand或HystrixObservableCommand如何與HystrixCircuitBreaker進行交互杉适,以及HystrixCircuitBreaker的決策邏輯流程,包括熔斷器內(nèi)部計數(shù)器如何工作柳击。
熔斷器執(zhí)行邏輯
線路的開路閉路詳細邏輯如下:
[圖片上傳失敗...(image-92804c-1691543452740)]
- 假設(shè)線路內(nèi)的容量(請求QPS)達到一定閾值(通過HystrixCommandProperties.circuitBreakerRequestVolumeThreshold()配置)
- 同時猿推,假設(shè)線路內(nèi)的錯誤率達到一定閾值(通過HystrixCommandProperties.circuitBreakerErrorThresholdPercentage()配置)
- 熔斷器將從『閉路』轉(zhuǎn)換成『開路』
- 若此時是『開路』狀態(tài),熔斷器將短路后續(xù)所有經(jīng)過該熔斷器的請求捌肴,這些請求直接走『失敗回退邏輯』
- **經(jīng)過一定時間(即『休眠窗口』蹬叭,通過HystrixCommandProperties.circuitBreakerSleepWindowInMilliseconds()配置),后續(xù)第一個請求將會被允許通過熔斷器(此時熔斷器處于『半開』狀態(tài))状知。
- 若該請求失敗秽五,熔斷器將又進入『開路』狀態(tài),且在休眠窗口內(nèi)保持此狀態(tài)饥悴;
- 若該請求成功坦喘,熔斷器將進入『閉路』狀態(tài)盲再,回到邏輯1循環(huán)往復(fù)。
<center> <font color=#0000FF>分享資源</font>
[圖片上傳失敗...(image-ddc3e1-1691543452740)]
掃碼 頭像 并關(guān)注發(fā)送:資源 獲取以上資源