一、前戲
Hystrix插件式對netflix.hystrix的一次封裝柳弄,簡單介紹下Hystrix
- 在2018年11月20日netflix已經(jīng)停止了對其維護(soul內(nèi)目前版本1.5.12)
- 目前市面大多數(shù)spring cloud項目,熔斷與降級組件使用的依舊是Hystrix
- 主要包括命令執(zhí)行(execution)配置概说、命令降級(fallback)配置碧注、熔斷器(circuit breaker)配置、度量統(tǒng)計(metrics)配置和請求上下文配置糖赔。
- 具有信號量模式與線程池模式
科普貼:http://www.reibang.com/p/dc0410558fc9
https://cloud.tencent.com/developer/article/1650056
二萍丐、soul-admin配置
- 開啟插件
運行Soul-admin,進入管理界面:系統(tǒng)管理 --> 插件管理 --> Hystrix 放典,點擊編輯逝变,把它開啟
配置選擇器選擇器參照divide的匹配方式,讓符合條件的http的請求奋构,能被捕獲到
- 配置規(guī)則
以下配置只是為了更容易出現(xiàn)測試效果壳影,生產(chǎn)環(huán)境請勿模仿
失敗降級URL在后面的測試中弥臼,測試失敗宴咧,應(yīng)該是根據(jù)請求格式有關(guān)。
個別配置項解釋:
- 命令key:
HystrixCommandKey是Hystrix命令的唯一標識醋火,準確來說是HystrixCommand實例或者HystrixObservableCommand實例的唯一標識悠汽。一般設(shè)置為具體的 路徑接口
- 分組key:
HystrixCommandGroupKey是用于對Hystrix命令進行分組,分組之后便于統(tǒng)計展示于儀表盤芥驳、上傳報告和預(yù)警等等柿冲,也就是說,HystrixCommandGroupKey是Hystrix內(nèi)部進行度量統(tǒng)計時候的分組標識兆旬,數(shù)據(jù)上報和統(tǒng)計的最小維度就是分組的KEY假抄。 一般設(shè)置為:contextPath
三、soul-Bootstrap
網(wǎng)關(guān)層需要引入依賴即可
<!-- soul hystrix plugin start-->
<dependency>
<groupId>org.dromara</groupId>
<artifactId>soul-spring-boot-starter-plugin-hystrix</artifactId>
<version>${last.version}</version>
</dependency>
<!-- soul hystrix plugin end-->
四丽猬、測試
- 測試用例來一發(fā)
觸發(fā)降級的兩個條件:滿足最大/最小并發(fā)量宿饱,或者達到異常比例。
所以使用wrk壓一下脚祟,讓流量先上到閾值谬以,便于觸發(fā)
wrk -t4 -c32 -d10s http://localhost:9195/http/test/findByUserId?userId=2
啟動測試一下::http://localhost:9195/http/test/findByUserId?userId=2
熔斷的返回值如下,fallback依舊是沒有成功由桌,可能跟格式有關(guān)系
{
"code": 500,
"message": "Internal Server Error",
"data": "/http/test/findByUserId short-circuited and fallback failed."
}
五为黎、源碼分析
插件鏈的調(diào)用此處不再分析邮丰,請參考之前文章,直奔主題HystrixPlugin##doExecute
@Override
protected Mono<Void> doExecute(final ServerWebExchange exchange, final SoulPluginChain chain, final SelectorData selector, final RuleData rule) {
// some code .....
// 將admin配置的rule實例化铭乾,json反序列化創(chuàng)建HystrixHandle對象剪廉,用于初始化Command
final HystrixHandle hystrixHandle = GsonUtils.getInstance().fromJson(rule.getHandle(), HystrixHandle.class);
// some code .....
// 創(chuàng)建HystrixCommand
Command command = fetchCommand(hystrixHandle, exchange, chain);
return Mono.create(s -> {
// 注冊完整執(zhí)行生命周期事件 :onCompleted、onError炕檩、onNext處理方式
Subscription sub = command.fetchObservable().subscribe(s::success,
s::error, s::success);
s.onCancel(sub::unsubscribe);
// 請求經(jīng)過command洗禮后斗蒋,判斷是否當(dāng)前已經(jīng)進入熔斷狀態(tài)
if (command.isCircuitBreakerOpen()) {
log.error("hystrix execute have circuitBreaker is Open! groupKey:{},commandKey:{}", hystrixHandle.getGroupKey(), hystrixHandle.getCommandKey());
}
}).doOnError(throwable -> {
// 通過調(diào)試,doExecute執(zhí)行異常笛质,比如timeout才會執(zhí)行此處
log.error("hystrix execute exception:", throwable);
exchange.getAttributes().put(Constants.CLIENT_RESPONSE_RESULT_TYPE, ResultEnum.ERROR.getName());
chain.execute(exchange);
}).then();
}
onCompleted:onNext/onError完成之后最后回調(diào)
onError:當(dāng)產(chǎn)生異常時回調(diào)
onNext:獲取結(jié)果后回調(diào)
在fetchCommand方法泉沾,用于生成是信號量模式還是線程池模式的Command
HystrixHandle中給了ExecutionIsolationStrategy默認信號量的默認值
六、小結(jié)
- 日拱一卒
- 疑問:Hystrix已經(jīng)停止維護了经瓷,真實項目使用此插件是否存在安全隱患爆哑?