【Hystrix技術(shù)指南】(5)Command創(chuàng)建和執(zhí)行實現(xiàn)

創(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í)行失敗回退邏輯侄柔,失敗原因可能是

  1. construct()或run()方法拋出異常HystrixBadRequestException除外
  2. 當線路是開路,導(dǎo)致命令被短路時
  3. 當命令對應(yīng)的線程池或信號量被占滿
  4. 執(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)]

  1. 假設(shè)線路內(nèi)的容量(請求QPS)達到一定閾值(通過HystrixCommandProperties.circuitBreakerRequestVolumeThreshold()配置)
  2. 同時猿推,假設(shè)線路內(nèi)的錯誤率達到一定閾值(通過HystrixCommandProperties.circuitBreakerErrorThresholdPercentage()配置)
  3. 熔斷器將從『閉路』轉(zhuǎn)換成『開路』
  4. 若此時是『開路』狀態(tài),熔斷器將短路后續(xù)所有經(jīng)過該熔斷器的請求捌肴,這些請求直接走『失敗回退邏輯』
  5. **經(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ā)送:資源 獲取以上資源

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末瓣铣,一起剝皮案震驚了整個濱河市洲胖,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌坯沪,老刑警劉巖绿映,帶你破解...
    沈念sama閱讀 217,907評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異腐晾,居然都是意外死亡叉弦,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,987評論 3 395
  • 文/潘曉璐 我一進店門藻糖,熙熙樓的掌柜王于貴愁眉苦臉地迎上來淹冰,“玉大人,你說我怎么就攤上這事巨柒∮K” “怎么了?”我有些...
    開封第一講書人閱讀 164,298評論 0 354
  • 文/不壞的土叔 我叫張陵洋满,是天一觀的道長晶乔。 經(jīng)常有香客問我,道長牺勾,這世上最難降的妖魔是什么正罢? 我笑而不...
    開封第一講書人閱讀 58,586評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮驻民,結(jié)果婚禮上翻具,老公的妹妹穿的比我還像新娘。我一直安慰自己回还,他們只是感情好裆泳,可當我...
    茶點故事閱讀 67,633評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著柠硕,像睡著了一般工禾。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上仅叫,一...
    開封第一講書人閱讀 51,488評論 1 302
  • 那天帜篇,我揣著相機與錄音糙捺,去河邊找鬼诫咱。 笑死,一個胖子當著我的面吹牛洪灯,可吹牛的內(nèi)容都是我干的坎缭。 我是一名探鬼主播竟痰,決...
    沈念sama閱讀 40,275評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼掏呼!你這毒婦竟也來了坏快?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,176評論 0 276
  • 序言:老撾萬榮一對情侶失蹤憎夷,失蹤者是張志新(化名)和其女友劉穎莽鸿,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體拾给,經(jīng)...
    沈念sama閱讀 45,619評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡祥得,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,819評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了蒋得。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片级及。...
    茶點故事閱讀 39,932評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖额衙,靈堂內(nèi)的尸體忽然破棺而出饮焦,到底是詐尸還是另有隱情,我是刑警寧澤窍侧,帶...
    沈念sama閱讀 35,655評論 5 346
  • 正文 年R本政府宣布县踢,位于F島的核電站,受9級特大地震影響伟件,放射性物質(zhì)發(fā)生泄漏殿雪。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,265評論 3 329
  • 文/蒙蒙 一锋爪、第九天 我趴在偏房一處隱蔽的房頂上張望丙曙。 院中可真熱鬧,春花似錦其骄、人聲如沸亏镰。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,871評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽索抓。三九已至,卻和暖如春毯炮,著一層夾襖步出監(jiān)牢的瞬間逼肯,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,994評論 1 269
  • 我被黑心中介騙來泰國打工桃煎, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留篮幢,地道東北人。 一個月前我還...
    沈念sama閱讀 48,095評論 3 370
  • 正文 我出身青樓为迈,卻偏偏與公主長得像三椿,于是被迫代替她去往敵國和親缺菌。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,884評論 2 354

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

  • 流程圖 下圖展示了當你使用 Hystrix 來包裝你請求依賴服務(wù)時的流程: 接下來將詳細介紹如下問題: 1.構(gòu)建H...
    KingsChan閱讀 5,999評論 0 21
  • 一搜锰、認識Hystrix Hystrix是Netflix開源的一款容錯框架伴郁,包含常用的容錯方法:線程池隔離、信號量隔...
    新棟BOOK閱讀 26,474評論 1 37
  • 一蛋叼、認識Hystrix Hystrix是Netflix開源的一款容錯框架焊傅,包含常用的容錯方法:線程池隔離、信號量隔...
    新棟BOOK閱讀 4,045評論 0 19
  • 原文:https://my.oschina.net/7001/blog/1619842 摘要: Hystrix是N...
    laosijikaichele閱讀 4,311評論 0 25
  • 簡介 在分布式環(huán)境中狈涮,許多服務(wù)依賴關(guān)系中的一些必然會失敗租冠。Hystrix是一個庫,它通過添加延遲容忍和容錯邏輯來幫...
    xbmchina閱讀 462評論 0 0