溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

如何理解SpringCloud Hystrix源碼解析

發(fā)布時間:2021-10-21 10:13:00 來源:億速云 閱讀:137 作者:iii 欄目:編程語言

本篇內(nèi)容主要講解“如何理解SpringCloud Hystrix源碼解析”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“如何理解SpringCloud Hystrix源碼解析”吧!

SpringCloud Hystrix源碼解析

看本篇之前請看

五分鐘學會 Spring Cloud Hystrix:服務(wù)容錯保護(小白必看,一看就會系列教程)

使用Hystrix 后的遠程調(diào)用流程如下:
1 )構(gòu)建HystrixCommand 或者Hys trixObservableCommand 對象。
2 )執(zhí)行命令。
3 )檢查是否有相同命令執(zhí)行的緩存。
4 )檢查斷路器是否打開。
5 )檢查線程池或者信號量是否被消耗完。
6 )調(diào)用Hystri xOb servabl eCommand#construct 或Hystri xCommand#run 執(zhí)行被封裝的遠程調(diào)用邏輯。
7 )計算鏈路的健康情況。
8 )在命令執(zhí)行失敗時獲取Fallback 邏輯。
9 )返回成功的Observable 。

封裝HystrixCommand

  1. @HystrixCommand 注解
    在基礎(chǔ)應(yīng)用中我們使用@HystrixCommand 注解來包裝需要保護的遠程調(diào)用方法。首先查看該注解的相關(guān)屬性,代碼如下所示:

/ / HystrixComrnand . Java@Target ( {
   
   
   Element Type . METHOD})@Retentio口( RetentionPolicy . RUNTIME)@Inherited@Document ed
pu b l 工C @int er face Hys t r ixComrnand {
   
   
   //命令分組鍵用于報告、預(yù)警以及面板展示
//默認為被注解方法的運行時類名
String groupKey() default//日ystr 工X 的命令鍵,用于區(qū)分不同的注解方法
//默認為注解方法的名稱
String commandKey () default//線程池鍵用來指定命令執(zhí)行的HystrixTh readPool
Str 工ng threadPoolKey () defaul t ”” ;第6 章斷路器Hystrix ?!? 125//指定Fallback方法名, Fallback方法也可以被HystrixCommand注解
String fallbackMethod () default//自定義命令的相關(guān)配置
HystrixProperty[) commandProperties() default {
   
   
   } ;//自定義線程池的相關(guān)配置
HystrixProperty [ J threadPoolProperties () default {
   
   
   } ;//定義忽略哪些異常
Class<? ext ends Throwable>[) ignoreExceptions() default {
   
   
   } ;//默認的fallback
String defaultFallback() default “”;}

如何理解SpringCloud Hystrix源碼解析
一般來說,對于HystrixCommand 的配置,僅需要關(guān)注fallbac燦fothod 方法,當然如果對命令和線程池有特定需要,可以進行額外的配置。除了@HystrixCommand 還有一個@Hystrix Collapser 注解用于請求合并操作,但是需要與@HystrixCommand 結(jié)合使用, 批量操作的方法必須被@HystrixCommand 注解。

  1. HystrixCommandAspect 切面
    被注解修飾的方法將會被HystrixCommand 包裝執(zhí)行,在Hystrix 中通過Aspectj 切面的方式來將被注解修飾的方法進行封裝調(diào)用。

1 )通過MetaHolderFactory 構(gòu)建出被注解修飾方法中用于構(gòu)建HystrixCommand 必要信息集合類MetaHolder 。
2 )根據(jù)MetaHolder 通過HystrixCommandFactory 構(gòu)建出合適的HystrixCommand 。
3 )委托CommandExecutor 執(zhí)行HystrixCommand ,得到結(jié)果。
MetaHolder 持有用于構(gòu)建HystrixCommand 和與被包裝方法相關(guān)的必要信息,如被注解的方法、失敗回滾執(zhí)行的方法和默認的命令鍵等屬性。

//MetaHolder . Java@Immutablepublic final class MetaHolder {
   
   
   private fina l Method method ; //被注解的方法
pr 工vate final Method cacheKeyMethod ;pri vate final Method ajcMethod ;private final Method fallbackMethod ; //失敗回滾執(zhí)行的方法private final String defaultGroupKey ; // 默認的group鍵private final String defaultCommandKey ; //默認的命令鍵private f inal String defaultCollapserKey ; //默認的合并請求鍵private f 工nal String defaultThreadPoolKey ; //默認的線程池鍵private final Executiontype executiontype ; I I 執(zhí)行類型}

在HystrixCommandFactory 類中,用于創(chuàng)建HystrixCommand 的方法如下所示:

//HystrixCommandFactory . javapublic Hystrxinvokable create(MetaHolder metaHolder) {
   
   
   HystriX invokable executable ;//構(gòu)建請求合并的命令if (metaHolder . isCollapserAnnotationPresent () ) (executable = new CommandCollapser(metaHolder) ;} else if (metaHolder isObservable()) (executable = 口ew GenericObservableCommand (HystrixCommandBui lderFactory .getinstance() create(metaHolder)) ;
 else (executable = new GenericCommand(Hystrix CommandBu lderFactory . getinstance() .create (metaHolder)) ;return executable;}

根據(jù)MetaHolder# isObservable 方法返回屬性的不同, 將會構(gòu)建不同的命令,比如HystrixCommand 或者HystrixObservableCommand ,前者將同步或者異步執(zhí)行命令, 后者異步回調(diào)執(zhí)行命令。Hystrix 根據(jù)被包裝方法的返回值來決定命令的執(zhí)行方式

如何理解SpringCloud Hystrix源碼解析
根據(jù)被包裝方法的返回值類型決定命令執(zhí)行的Execution Type ,從而決定構(gòu)建HystrixCommand 還是HystrixObservableCommand 。其中Future 類型的返回值將會被異步執(zhí)行, rx 類型的返回值將會被異步回調(diào)執(zhí)行,其他的類型將會被同步執(zhí)行。
CommandExecutor 根據(jù)MetaHolder 中ExecutionType 執(zhí)行類型的不同,選擇同步執(zhí)行、異步執(zhí)行還是異步回調(diào)執(zhí)行,返回不同的執(zhí)行結(jié)果。同步執(zhí)行,直接返回結(jié)果對象;異步執(zhí)行,返回Future ,封裝了異步操作的結(jié)果;異步回調(diào)執(zhí)行將返回Observable ,封裝響應(yīng)式
執(zhí)行的結(jié)果,可以通過它對執(zhí)行結(jié)果進行訂閱,在執(zhí)行結(jié)束后進行特定的操作。
如何理解SpringCloud Hystrix源碼解析

HystrixCommand 類結(jié)構(gòu)

如何理解SpringCloud Hystrix源碼解析
雖然類圖很復(fù)雜,但是最終實現(xiàn)類只有三個,分別是同步或異步執(zhí)行命令的GenericCommand ; 請求合并執(zhí)行命令的BatchHystrixCommand , 以及異步回調(diào)執(zhí)行命令的GenericObservableCommand

異步回調(diào)執(zhí)行命令

在observe 方法中, 首先將創(chuàng)建一個方法ReplaySu均ect, rx 中的Subject 既是一個Observable 也是一個Observer 。接著調(diào)用toObservable 方法獲取到懶執(zhí)行的Observable,通過創(chuàng)建的ReplaySubject 訂閱該Observable ,啟動Observable 中相關(guān)命令, 同時返回ReplaySubject 給后續(xù)的觀察者,用于訂閱來獲取執(zhí)行結(jié)果( ReplaySubject 會推送所有來自原始Observable 的事件給觀察者,無論它們是何時訂閱的) 。

AbstractCommand#toObservable
1 ) 首先通過Observable#defer 方法來構(gòu)建返回的Observable a 以O(shè)bservable#defer 方式聲明的Observable 只有當有觀察者訂閱才會真正開始創(chuàng)建,并且是為每一個觀察者創(chuàng)建一個新的Observable ,這就保證了toObservable 方法返回的Observable 是純凈的,并沒有
開始執(zhí)行命令。
2 )在構(gòu)建Observable 過程中,先通過commandState 查看當前的命令執(zhí)行狀態(tài),保證命令未開始執(zhí)行并且每條命令只能執(zhí)行一次。
3 )如果允許請求緩存并且緩存存在的話,將嘗試從緩存中獲取對應(yīng)的執(zhí)行結(jié)果,并直接返回結(jié)果。
4 )如果無法獲取緩存,通過applyHystrixSemantics 方法構(gòu)建用于返回的Observable 。
5 )如果允許請求緩存,將ObsErvable 放置到緩存中用于下一次調(diào)用。
6 ) 最后為返回Observable 添加提前定義好的回調(diào)方法。
在上述的流程中,需要重點關(guān)注兩個地方,一個是HystrixRequestCache ,其內(nèi)封裝了
緩存Observable 的邏輯;另一個是applyHystrix Semantics 回調(diào)方法,其內(nèi)封裝了斷路、資源隔離等核心斷路器邏輯。

·HystrixRequestCache 請求援存
HystrixRequestCache 對Observable 進行緩存操作,使用每個命令特有的cacheKey 對Observable 進行緩存,通過ConcurrentHashMap 保存緩存結(jié)果以保證線程安全。

HystrixRequestCache 中緩存的并不是直接的Observable , 而是被封裝好的HystrixCachedObservable。在HystrixCachedObservable 中,通過ReplaySubject 訂閱需要緩存的Observable ,保證了緩存的Observable 能夠多次執(zhí)行.

applyHystrixSemantics 斷路器判斷與獲取信號量
在applyHystrixSemantics 回調(diào)方法中, 通過AbstractCommand#app ly HystrixSemantics方法聲明Observable 。它主要工作是判斷斷路器是否打開, 以及嘗試獲取信號量用于執(zhí)行命令(僅在信號量隔離模式下生效)
在AbstractColilIIland#applyHystrix.Semant ic s 中, 首先通過斷路器Hystrix.CircuitBreaker 檢查鏈路中的斷路器是否開啟, 如果開啟的話,執(zhí)行斷路失敗邏輯handleShortCircuitViaFallback方法。如果通過斷路器的檢查, 將會嘗試獲取信號量。如果不能獲取信號量,那么執(zhí)行信號量獲取失敗邏輯handleSemaphoreRejection ViaFallback 方法。當上述檢查都通過了,才執(zhí)行exec uteCornmandAndObserve 方法獲取執(zhí)行命令的Observable , 并為該Observable 配置
回調(diào)操作, 該回調(diào)操作在命令執(zhí)行結(jié)束后以及取消訂閱時用于釋放信號量。

executeCommandAndObserve 配置執(zhí)行異常回調(diào)方法
executeCommandAndObserve 方法主要用于為執(zhí)行命令Observable 配置執(zhí)行失敗的回調(diào)方法,對執(zhí)行失敗的結(jié)果進行記錄和處理。

executeCo mm an dWith Specifiedlsolation 配置線程隔離和超時控制
executeCommandW ithSpeci fiedlsolatio n 方法為命令構(gòu)造了隔離的執(zhí)行環(huán)境,提供兩種資源隔離的方式, 線程隔離和信號量隔離;如果Hystrix 配置中開啟了超時控制,還會通過Observable#lift 方法將現(xiàn)有的Observable 轉(zhuǎn)化為添加了超時檢查的Observable 。

getExecutionObservable 配置被封裝的遠程調(diào)用方法
getUserEx巳cutionObservable 方法將為命令獲取在聲明HystrixCommand 時被包裝的具
體遠程調(diào)用方法。在getUserExec utionObservable 方法中,通過getExecutionObservable 抽象方法將具體實現(xiàn)延遲到子類中

到此,相信大家對“如何理解SpringCloud Hystrix源碼解析”有了更深的了解,不妨來實際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進入相關(guān)頻道進行查詢,關(guān)注我們,繼續(xù)學習!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI