沒有使用過hystrix,需要了解hystrix原理:How-it-Works
整體流程
1.構造一個 HystrixCommand
或者HystrixObservableCommand
對象
2.執行命令
3.是否返回值已經緩存?
4.是否打開斷路器?
5.是否線程池/隊列/型號量已滿?
6.執行HystrixObservableCommand.construct()
或者HystrixCommand.run()
方法
7.計算線路健康值
8.獲取fallback
基于本地緩存的 fallback 降級機制
9.返回請求成功的數據
1.構造一個HystrixCommand
或HystrixObservableCommand
對象
第一步是構造一個HystrixCommand
或HystrixObservableCommand
對象,表示對依賴發起的請求。向構造函數傳在請求的時所需要的參數
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
返回給您之前,可能會對其進行轉換:
-
execute()
-獲得Future
的相同方式一樣.queue()
,然后調用get()
在此Future
以獲得由所發射的單個值Observable
-
queue()
—將轉換Observable
為,BlockingObservable
以便可以將其轉換為Future
,然后返回Future
-
observe()
—Observable
立即訂閱并開始執行命令的流程;返回一個Observable
,當您subscribe
重播時,它會排放和通知 -
toObservable()
—返回Observable
不變;您必須先subscribe
執行此命令才能真正開始導致執行命令的流程