SpringCloud Hystrix原始碼決議(三)
看這篇之前請看
SpringCloud Hystrix原始碼決議(一)
SpringCloud Hystrix原始碼決議(二)
異步與異步回呼執行命令
Hystrix 除了同步執行命令,還可以異步以及異步回呼執行命令,異步執行命令需要定義函式的回傳方式為Future ,如下面的例子所示:
@HystrixCommand(fallbackMethod =”instanceinfoGetFailAsync ” )
public Future<Instance> getinstanceByServ 工ceidAsync(String serviceid) {
logger.info (” Can not get Instance by serviceid {} ”, serviceid) ;
return new AsyncResult <Instance> () {
@Override
public Instance invoke() {
return restTemplate . getForEntity ( ” http : //FEIGN SERVICE/fe ign serv工ce/
instance/{serviceid} ”, Instance . class , serviceid) . getBody() ;
}
};
}
在這種情況下,命令的失敗回滾方法也需要通過@HystrixCommand 進行注解,如下所示:
@HystrixCommand
public Future<Instance >Instance InfoGetFailAsync(String serviceid){
logger 工nfo( " Can not get Instance by serviceid {} ”, serviceid) ;
return new AsyncResult <工nsta口Ce> () {
@Override
public Instance Invoke() {
return new Instance ( ” error ",” error ”, ,) ;
}
};
}
同樣, 想要異步回呼執行命令, 只需要將包裝函式的回傳值設定為Observable 即可,如下所示:

異步回呼執行命令并不需要Fallback 方法被@HystrixCommand 注解,可以通過設定observableExecutionMode 來決定回傳的Observable 是否已經開始執行命令: EAGER 將會回傳通過AbstractCommand#observable 方法生成的Observable 此時的命令已經開始執行了;而LAZY 則會回傳通過AbstractCommand#toObservable 方法生成的Observable , 回傳的
Observale 必須訂閱后才會真正開始執行命令,上面的例子中設定的observableExecutionMode為ObservableExecutionMode.LAZY ,
繼承HystrixCommand
除了通過注解的方式宣告Hystrix 包裝函式,還可以通過繼承Hystrix Command 以及HystrixObservableCommand 抽象類介面來包裝需要保護的遠程呼叫函式,
繼承HystrixCommand
下面將通過繼承HystrixCommand 抽象類來實作特定的HystrixCommand 子類,代碼如下所示:

run 方法中是需要進行包裝的遠程呼叫函式, 是必須要實作的抽象方法, getFallback方法是該命令執行失敗后的失敗回滾方法,屬于可選實作,值得注意的是,在構造HystrixCommand 時-至少要為它指定一個HystrixCommandGroupKey ,在通過注解的方式生
成HystrixCommand 時,該值一般是注解方法所在類的運行時類名,
在使用C ustomH ystrixCommand 時,會發現無法在#run 方法中傳遞引數,所以需要在構造器中攜帶# run 方法的相關引數,如上述例子中的建構式,傳遞被保護方法執行所需要的引數:
protected CustomHystrixCommand(RestTemplate restTemplate, String serviceid) { . . . }
呼叫命令的方式很簡單,如下所示:
CustomH.ystrixCommand customHystrixCommand = new CustomHystrixCommand(restTemplate ,serviceid);
Instance instance = customHystrixCommand . execute();
創建一個CustomHystrixCommand , 并呼叫它的execute 方法, 即可按照Hystrix 的邏輯執行命令,如果想要以異步方式執行命令,可以呼叫它的queue 方法,如下所示:
CustomHystrixCommand customH.ystrixCommand = new CustomHystrixCommand(restTemplate,
serviceid) ;
Future<Instance> future= customHystrixCommand . queue() ;
還需要注意的是,一個C ustomHystrixComman d 只能執行一次( execute 方法或者queue方法),所以每次使用都要創建一個新的Command ,為了滿足自定義HystrixCommand 配置的需求, HystrixCommand 抽象類中定義了多種構造器,用于對構建的Command 配置進行設定,
繼承HystrixObservableCommand
除了HystrixCommand ,還可以繼承HystrixObservableCommand 來構建以異步回呼執行命令的Command
請求合并
Hystrix 還提供了請求合并的功能,多個請求被合并為一個請求進行一次性處理,可以有效減少網路通信和執行緒池資源,請求合并之后一個請求原本可能在6 毫秒之內能夠結束, 現在必須等待請求合并周期后( I 0 毫秒)才能發送請求,增加了請求的時間( 16 毫秒) ,但是請求合并在處理高并發和高延遲命令上效果極佳,
它提供兩種方式進行請求合并: request-scoped 收集一個Hystrix RequestContext 中的請求集合成一個批次;而globally-scoped 將多個HystrixRequestContext 中的請求集合成一個批次,這需要應用的下游依賴能夠支持在一個命令呼叫中處理多個HystrixRequestContext ,
HystrixReuestContext 中包含和管理著HystrixRquestVariableDefault , HystrixRequestγariableDefault中提供了請求范圍內的相關變數,所以在同一請求中的多個執行緒可以分享狀態,HystrixRequestContext 也可以通過Hystri xRequestVari ableDefault 收集到請求范圍內相同的HystrixCommand 進行合并,
通過注解方式進行請求合并
單個請求需要使用@HystrixCollapser 注解修飾,并指batchMethod 方法,這里我們設定請求合并的周期為100 秒,由于請求合并中不能同步等待結果,所以單個請求回傳的結果為Future ,即需要異步等待結果,
batchMethod 方法需要被@Hystri x Command 注解,說明這是一個被HystrixCommand封裝的方法
請求開始前需要為請求初始化HystrixRequestContext ,用于在同一請求中的執行緒間共享資料,封裝批量請求,請求結束前需要關閉HystrixRequestContext
結果顯示只執行了兩次批量操作,前三個為一次,最后一個單獨進行,如果在請求合并周期內直接呼叫Future#get 方法阻塞等待同步結果,將會強行合并請求,增加遠程請求次數
主執行緒將會因為同步等待而阻塞后面命令沒有提交合并,請求合并只進行到test2中,所以上面代碼中將會執行三次批量請求,前兩個為一次,第三個和第四個分別為
一次,
繼承HystrixCollapser
請求合并命令同樣也可以通過自定義的方式實作, 只需繼承HystrixCollapser 抽象類
在建構式中需要指定CollapserKey,用來標記被合并請求的鍵值,CustomCollapseCommand樣可以通過Setter 的方式修改默認配置,
同時還需要實作三個方法, getRequestArgument 方法獲取被合并的單個請求的引數,createCommand 方法用來生成進行批量請求的命令Command, mapResponseToRequests 方法是將批量請求的結果與合并的請求進行匹配以回傳對應的請求結果,
需要注意的是,因為HystrixCollapser 繼承了Hystrixlnvokable ,它同樣提供execute 同步獲取結果,但是呼叫execute 獲取結果時,會因為同步等待的原因阻塞主執行緒,導致后面的請求無法提交合并,增加遠程呼叫的次數,
總結
微服務架構下,每個微服務獨立部署運行,業務之間的搞合使微服務間不可避免地會發生相互呼叫,由于網路故障或者程式故障,服務提供者很容易無法回應服務呼叫者的請求,引起服務雪崩,最壞情況下可能導致整個分布式系統的癱瘓,Hystrix 為S pri ng C l ou d 中微服務間的相互呼叫提供了強大的容錯保護,它通過將服務呼叫者和服務提供者隔離的方式,在服務提供者失效的情況下,保護服務呼叫者的執行緒資源,保證系統的整體穩定性,防止服務雪崩效應的發生,Hys trix 提供了很多服務容錨的機制和手段,如斷路器、資源隔離、失敗回滾等,同時也提供接近實時的執行監控,為服務的健康運行保駕護航,
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/242861.html
標籤:其他
