一.執行流程緩存
1.首先,tomcat接收訪問請求,開啓調用線程調用依賴服務。tomcat
2.在調用依賴服務以前,建立command網絡
3.在執行command以前,查找hystrix的request cache,若是緩存有數據,直接返回,不然執行command調用依賴服務返回數據異步
4.斷路器統計成功次數、異常次數,若是打開了斷路設置,直接降級函數
5.若是沒打開斷路設置,判斷線程池/信號量是否已滿,若是滿了,直接降級ui
6.若是沒有滿,執行command,若是超時,則降級,若是報錯,則也降級處理,若是執行成功,則返回數據,同時向斷路器發送事件,供斷路起統計。spa
7.若是打開了斷路器設置,直接降級處理線程
二.代碼實現流程 code
一、構建一個HystrixCommand或者HystrixObservableCommand,一個HystrixCommand或一個HystrixObservableCommand對象,表明了對某個依賴服務發起的一次請求或者調用,構造的時候能夠在構造函數中傳入任何須要的參數。server
HystrixCommand command = new HystrixCommand(arg1, arg2); HystrixObservableCommand command = new HystrixObservableCommand(arg1, arg2);
2.執行command
execute():調用後直接block住,屬於同步調用,直到依賴服務返回單條結果,或者拋出異常
queue():返回一個Future,屬於異步調用,後面能夠經過Future獲取單條結果
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()去執行的。
3.檢查是否開啓緩存
若是這個command開啓了請求緩存,request cache,並且這個調用的結果在緩存中存在,那麼直接從緩存中返回結果
4.檢查是否開啓了短路器
檢查這個command對應的依賴服務是否開啓了斷路器;若是斷路器被打開了,那麼hystrix就不會執行這個command,而是直接去執行fallback降級機制
5.檢查線程池/隊列/semaphore是否已經滿了
若是command對應的線程池/隊列/semaphore已經滿了,那麼也不會執行command,而是直接去調用fallback降級機制
6.執行command
調用HystrixObservableCommand.construct()或HystrixCommand.run()來實際執行這個command
HystrixCommand.run()是返回一個單條結果,或者拋出一個異常
HystrixObservableCommand.construct()是返回一個Observable對象,能夠獲取多條結果
若是HystrixCommand.run()或HystrixObservableCommand.construct()的執行,超過了timeout時長的話,那麼command所在的線程就會拋出一個TimeoutException
若是timeout了,也會去執行fallback降級機制,並且就不會管run()或construct()返回的值了。
這裏要注意的一點是,咱們是不可能終止掉一個調用嚴重延遲的依賴服務的線程的,只能說給你拋出來一個TimeoutException,可是仍是可能會由於嚴重延遲的調用線程佔滿整個線程池的,即便這個時候新來的流量都被限流了。若是沒有timeout的話,那麼就會拿到一些調用依賴服務獲取到的結果,而後hystrix會作一些logging記錄和metric統計。
7.短路健康檢查
Hystrix會將每個依賴服務的調用成功,失敗,拒絕,超時,等事件,都會發送給circuit breaker斷路器,斷路器就會對調用成功/失敗/拒絕/超時等事件的次數進行統計,斷路器會根據這些統計次數來決定,是否要進行斷路,若是打開了斷路器,那麼在一段時間內就會直接斷路,而後若是在以後第一次檢查發現調用成功了,就關閉斷路器。
8.調用fallback降級機制
在如下幾種狀況中,hystrix會調用fallback降級機制:run()或construct()拋出一個異常,斷路器打開,線程池/隊列/semaphore滿了,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方法
9.不一樣的執行方式
execute(),獲取一個Future.get(),而後拿到單個結果 queue(),返回一個Future observer(),當即訂閱Observable,而後啓動8大執行步驟,返回一個拷貝的Observable,訂閱時直接回調給你結果 toObservable(),返回一個原始的Observable,必須手動訂閱纔會去執行8大步驟