五、 深入分析hystrix執行時流程以及內部原理

5.1 構建一個HystrixCommand|HystrixObservableCommand

一個HystrixCommand或一個HystrixObservableCommand對象,代表了對某個依賴服務發起的一次請求或者調用

 

構造的時候,可以在構造函數中傳入任何需要的參數

HystrixCommand主要用於僅僅會返回一個結果的調用

HystrixObservableCommand主要用於可能會返回多條結果的調用

 

HystrixCommand command = new HystrixCommand(arg1, arg2);

HystrixObservableCommand command = new HystrixObservableCommand(arg1, arg2);

 

5.2 調用command的執行方法

執行Command就可以發起一次對依賴服務的調用

要執行Command,需要在4個方法中選擇其中的一個:execute(),queue(),observe(),toObservable()

 

execute()和queue()對HystrixCommand適用

execute():調用後直接block住,屬於同步調用,直到依賴服務返回單條結果,或者拋出異常

queue():返回一個Future,屬於異步調用,後面可以通過Future獲取單條結果

observe()與toObservable()對於HystrixObservableCommand適用

observe():訂閱一個Observable對象,Observable代表的是依賴服務返回的結果,獲取到一個那個代表結果的Observable對象的拷貝對象

toObservable():返回一個Observable對象,如果我們訂閱這個對象,就會執行command並且獲取返回結果

 

K             value   = command.execute();

Future<K>     fValue  = command.queue();

Observable<K> ohValue = command.observe();         

Observable<K> ocValue = command.toObservable();    

 

execute()實際上會調用queue().get().queue(),接着會調toObservable().toBlocking().toFuture()

也就是說,無論是哪種執行command的方式,最終都是依賴toObservable()去執行的

 

5.3 檢查是否開啓緩存

從這一步開始,進入我們的底層的運行原理啦,瞭解hysrix的一些更加高級的功能和特性

如果這個command開啓了請求緩存,request cache,而且這個調用的結果在緩存中存在,那麼直接從緩存中返回結果

5.4 檢查是否開啓了短路器

檢查這個command對應的依賴服務是否開啓了短路器

如果斷路器被打開了,那麼hystrix就不會執行這個command,而是直接去執行fallback降級機制

5.5 檢查線程池/隊列/semaphore是否已經滿了

如果command對應的線程池/隊列/semaphore已經滿了,那麼也不會執行command,而是直接去調用fallback降級機制

5.6 執行command

調用HystrixObservableCommand.construct()或HystrixCommand.run()來實際執行這個command

HystrixCommand.run()是返回一個單條結果,或者拋出一個異常

HystrixObservableCommand.construct()是返回一個Observable對象,可以獲取多條結果

如果HystrixCommand.run()或HystrixObservableCommand.construct()的執行,超過了timeout時長的話,那麼command所在的線程就會拋出一個TimeoutException

如果timeout了,也會去執行fallback降級機制,而且就不會管run()或construct()返回的值了

這裏要注意的一點是,我們是不可能終止掉一個Hystrix調用嚴重延遲的依賴服務的線程的,只能說給你拋出來一個主線程TimeoutException(Semaphore不會),但是還是可能會因爲嚴重延遲的調用線程佔滿整個線程池的

即使這個時候新來的流量都被限流了。。。

如果沒有timeout的話,那麼就會拿到一些調用依賴服務獲取到的結果,然後Hystrix會做一些logging記錄和metric統計

 

5.7 短路健康檢查

Hystrix會將每一個依賴服務的調用成功,失敗,拒絕,超時,等事件,都會發送給circuit breaker短路器

短路器就會對調用成功/失敗/拒絕/超時等事件的次數進行統計

短路器會根據這些統計次數來決定,是否要進行短路,如果打開了短路器,那麼在一段時間內就會直接短路,然後如果在之後第一次檢查發現調用成功了,就關閉斷路器

 

5.8 調用fallback降級機制

在以下幾種情況中,hystrix會調用fallback降級機制:

(1)、run()或construct()拋出一個異常

(2)、短路器打開,

(3)、線程池/隊列/semaphore滿了,

(4)、command執行超時了

 

一般在降級機制中,都建議給出一些默認的返回值,比如靜態的一些代碼邏輯,或者從內存中的緩存中提取一些數據,儘量在這裏不要再進行網絡請求了

 

即使在降級中,一定要進行網絡調用,也應該將那個調用放在一個HystrixCommand中,進行隔離

 

在HystrixCommand中,上線getFallback()方法,可以提供降級機制

在HystirxObservableCommand中,實現一個resumeWithFallback()方法,返回一個Observable對象,可以提供降級結果。如果fallback返回了結果,那麼hystrix就會返回這個結果

 

對於HystrixCommand,會返回一個Observable對象,其中會發返回對應的結果

對於HystrixObservableCommand,會返回一個原始的Observable對象

如果沒有實現fallback,或者是fallback拋出了異常,Hystrix會返回一個Observable,但是不會返回任何數據

 

不同的command執行方式,其fallback爲空或者異常時的返回結果不同

對於execute(),直接拋出異常

對於queue(),返回一個Future,調用get()時拋出異常

對於observe(),返回一個Observable對象,但是調用subscribe()方法訂閱它時,理解拋出調用者的onError方法

對於toObservable(),返回一個Observable對象,但是調用subscribe()方法訂閱它時,理解拋出調用者的onError方法

 

execute(),獲取一個Future.get(),然後拿到單個結果

queue(),返回一個Future

observer(),立即訂閱Observable,然後啓動8大執行步驟,返回一個拷貝的Observable,訂閱時理解回調給你結果

toObservable(),返回一個原始的Observable,必須手動訂閱纔會去執行8大步驟

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章