Soul源碼閱讀 hystrix【第十九天】

沒有使用過hystrix,需要了解hystrix原理:How-it-Works

整體流程

image.png

1.構造一個 HystrixCommand或者HystrixObservableCommand對象
2.執行命令
3.是否返回值已經緩存?
4.是否打開斷路器?
5.是否線程池/隊列/型號量已滿?
6.執行HystrixObservableCommand.construct() 或者HystrixCommand.run()方法
7.計算線路健康值
8.獲取fallback 基于本地緩存的 fallback 降級機制
9.返回請求成功的數據

1.構造一個HystrixCommandHystrixObservableCommand對象

第一步是構造一個HystrixCommandHystrixObservableCommand對象,表示對依賴發起的請求。向構造函數傳在請求的時所需要的參數

HystrixCommand如果期望依賴項返回單個響應,則構造一個對象。例如:

HystrixCommand command = new HystrixCommand(arg1, arg2);

HystrixObservableCommand 如果希望依賴項返回一個發出響應的Observable,則構造一個對象。例如:

HystrixObservableCommand command = new HystrixObservableCommand(arg1, arg2);

2.執行命令

使用Hystrix命令對象的以下四種方法之一可以執行命令的方式有四種(前兩種僅適用于簡單HystrixCommand對象,不適用于HystrixObservableCommand):

  • execute() - 阻塞,然后返回從依賴項接收到的單個響應(或在發生錯誤的情況下拋出異常)
  • queue() - 返回一個Future,可以從中獲取依賴項的單個響應
  • observe() - 訂閱,該Observable代表了來自依賴項的響應,并返回了一個Observable復制源的。Observable
  • toObservable() - 返回一個Observable,當您訂閱它時,將執行Hystrix命令并發出其響應
K             value   = command.execute();
Future<K>     fValue  = command.queue();
Observable<K> ohValue = command.observe();         //hot observable
Observable<K> ocValue = command.toObservable();    //cold observable

同步調用execute()調用queue().get()queue()依次調用toObservable().toBlocking().toFuture()。這就是說,最終每個實現HystrixCommand都由Observable實現支持,即使是那些旨在返回單個簡單值的命令也是如此。

3.響應是否已緩存?

如果為此命令啟用了請求緩存,并且如果對請求的響應在緩存中可用,則該緩存的響應將立即以的形式返回Observable。(請參見下面的“請求緩存”

4.電路是否開路?

當您執行該命令時,Hystrix會檢查斷路器,以查看電路是否斷開。

如果電路開路(或“跳閘”),那么Hystrix將不執行命令,而是將流路由到(8)獲取回退。

如果電路閉合,則流程前進至(5),以檢查是否有足夠的容量來運行命令。

5.線程池/隊列/信號量是否已滿?

如果與該命令關聯的線程池和隊列(或信號量,如果未在線程中運行)已滿,即到達斷路條件,則Hystrix將不執行該命令,但會立即將流路由到(8)獲取回退。

6.HystrixObservableCommand.construct()HystrixCommand.run()

在這里,Hystrix通過為此目的編寫的方法(以下之一)調用對依賴項的請求:

  • HystrixCommand.run() —返回單個響應或引發異常
  • HystrixObservableCommand.construct()—返回一個Observable,它發出響應或發送onError通知

如果run()orconstruct()方法超出命令的超時值,則該線程將拋出TimeoutException(如果命令本身未在其自己的線程中運行,則該線程將拋出單獨的計時器線程)。在那種情況下,Hystrix通過8路由響應。獲取Fallback,如果該方法沒有取消/中斷,它將丟棄最終的返回值run()construct()方法。

請注意,沒有辦法強制潛在線程停止工作-Hystrix在JVM上能做的最好的事情就是將其拋出InterruptedException。如果Hystrix封裝的工作不遵守InterruptedExceptions,盡管客戶端已經收到TimeoutException,Hystrix線程池中的線程仍將繼續工作。盡管負載已“正確釋放”,但此行為可能會使Hystrix線程池飽和。大多數Java HTTP客戶端庫不解釋InterruptedExceptions。因此,請確保在HTTP客戶端上正確配置連接和讀取/寫入超時。

如果命令沒有引發任何異常并且返回了響應,則Hystrix在執行一些日志記錄和度量標準報告后將返回此響應。在的情況下run(),Hystrix返回Observable發出單個響應并發出onCompleted通知的;在的情況下construct()猬返回相同Observable的返回construct()。

7.計算電路健康

Hystrix向斷路器報告成功,失敗,拒絕和超時,斷路器保持滾動的一組計數器來計算統計信息。

它使用這些統計信息來確定電路何時應“跳閘”,在此點它會將隨后的所有請求短路,直到經過恢復期為止,在此之后,在首先檢查某些運行狀況檢查之后,它將再次閉合電路。

8.獲取后備

Hystrix試圖在命令執行失敗時恢復到您的后備狀態:當construct()或引發異常run()(6.),由于電路斷開而使命令短路(4.),命令的線程池和隊列或信號量為最大容量(5.),或者命令已超過其超時長度。

編寫后備,以從內存中的緩存或通過其他靜態邏輯提供通用響應,而無需任何網絡依賴性。如果必須在回退中使用網絡呼叫,則應通過另一個HystrixCommand或進行HystrixObservableCommand

對于HystrixCommand,要提供后備邏輯,您可以實現HystrixCommand.getFallback()該邏輯,該邏輯將返回單個后備值。

對于HystrixObservableCommand,要提供后備邏輯,您可以實現HystrixObservableCommand.resumeWithFallback()它返回一個Observable,它可能會發出一個或多個后備值。

如果fallback方法返回響應,則Hystrix將把此響應返回給調用方。對于a HystrixCommand.getFallback(),它將返回一個Observable,它發出從該方法返回的值。在這種情況下,HystrixObservableCommand.resumeWithFallback()它將返回從方法返回的相同Observable。

如果尚未為Hystrix命令實現后備方法,或者后備本身引發異常,則Hystrix仍返回一個Observable,但該對象不發出任何內容并立即以onError通知終止。通過該onError通知,將導致命令失敗的異常發送回調用方。(實施回退實現可能會失敗,這是一個糟糕的做法。您應該實施回退,以使其不執行任何可能失敗的邏輯。)

后備失敗或不存在的后備結果將因調用Hystrix命令的方式而異:

  • execute() -引發異常
  • queue()—成功返回Future,但是Future如果get()調用其方法,則會拋出異常
  • observe()—返回一個Observable,當您訂閱它時,將通過調用訂閱者的onError方法立即終止
  • toObservable()—返回一個Observable,當您訂閱時,它將通過調用訂閱者的onError方法終止

9.返回成功的回應

如果Hystrix命令成功執行,它將以的形式將一個或多個響應返回給調用方Observable。根據您在上面的步驟2中調用命令的方式,在Observable返回給您之前,可能會對其進行轉換:

image.png
  • execute()-獲得Future的相同方式一樣.queue(),然后調用get()在此Future以獲得由所發射的單個值Observable
  • queue()—將轉換Observable為,BlockingObservable以便可以將其轉換為Future,然后返回Future
  • observe()Observable立即訂閱并開始執行命令的流程;返回一個Observable,當您subscribe重播時,它會排放和通知
  • toObservable()—返回Observable不變;您必須先subscribe執行此命令才能真正開始導致執行命令的流程
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,327評論 6 537
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,996評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 177,316評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,406評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,128評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,524評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,576評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,759評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,310評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,065評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,249評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,821評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,479評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,909評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,140評論 1 290
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,984評論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,228評論 2 375

推薦閱讀更多精彩內容