soul从入门到放弃11--浅入浅出Hystrix插件

一、前戏

Hystrix插件式对netflix.hystrix的一次封装,简单介绍下Hystrix

  • 在2018年11月20日netflix已经停止了对其维护(soul内目前版本1.5.12)
  • 目前市面大多数spring cloud项目,熔断与降级组件使用的依旧是Hystrix
  • 主要包括命令执行(execution)配置、命令降级(fallback)配置、熔断器(circuit breaker)配置、度量统计(metrics)配置和请求上下文配置。
  • 具有信号量模式与线程池模式

科普贴:https://www.jianshu.com/p/dc0410558fc9

https://cloud.tencent.com/developer/article/1650056

二、soul-admin配置

  • 开启插件

运行Soul-admin,进入管理界面:系统管理 --> 插件管理 --> Hystrix ,点击编辑,把它开启

配置选择器选择器参照divide的匹配方式,让符合条件的http的请求,能被捕获到

image.png
  • 配置规则

以下配置只是为了更容易出现测试效果,生产环境请勿模仿

image.png

失败降级URL在后面的测试中,测试失败,应该是根据请求格式有关。

个别配置项解释:

  • 命令key:

HystrixCommandKey是Hystrix命令的唯一标识,准确来说是HystrixCommand实例或者HystrixObservableCommand实例的唯一标识。一般设置为具体的 路径接口

  • 分组key:

HystrixCommandGroupKey是用于对Hystrix命令进行分组,分组之后便于统计展示于仪表盘、上传报告和预警等等,也就是说,HystrixCommandGroupKey是Hystrix内部进行度量统计时候的分组标识,数据上报和统计的最小维度就是分组的KEY。 一般设置为:contextPath

三、soul-Bootstrap

网关层需要引入依赖即可


  
      org.dromara
      soul-spring-boot-starter-plugin-hystrix
       ${last.version}
  
  

四、测试

  • 测试用例来一发

触发降级的两个条件:满足最大/最小并发量,或者达到异常比例。

所以使用wrk压一下,让流量先上到阈值,便于触发

wrk -t4 -c32 -d10s http://localhost:9195/http/test/findByUserId?userId=2

启动测试一下::http://localhost:9195/http/test/findByUserId?userId=2

熔断的返回值如下,fallback依旧是没有成功,可能跟格式有关系

{
    "code": 500,
    "message": "Internal Server Error",
    "data": "/http/test/findByUserId short-circuited and fallback failed."
}

五、源码分析

插件链的调用此处不再分析,请参考之前文章,直奔主题HystrixPlugin##doExecute

@Override
protected Mono doExecute(final ServerWebExchange exchange, final SoulPluginChain chain, final SelectorData selector, final RuleData rule) {
    // some code  .....
    // 将admin配置的rule实例化,json反序列化创建HystrixHandle对象,用于初始化Command
    final HystrixHandle hystrixHandle = GsonUtils.getInstance().fromJson(rule.getHandle(), HystrixHandle.class);
    // some code  .....
    // 创建HystrixCommand
    Command command = fetchCommand(hystrixHandle, exchange, chain);
    return Mono.create(s -> {
    // 注册完整执行生命周期事件 :onCompleted、onError、onNext处理方式
        Subscription sub = command.fetchObservable().subscribe(s::success,
                s::error, s::success);
        s.onCancel(sub::unsubscribe);
        // 请求经过command洗礼后,判断是否当前已经进入熔断状态
        if (command.isCircuitBreakerOpen()) {
            log.error("hystrix execute have circuitBreaker is Open! groupKey:{},commandKey:{}", hystrixHandle.getGroupKey(), hystrixHandle.getCommandKey());
        }
    }).doOnError(throwable -> {
        // 通过调试,doExecute执行异常,比如timeout才会执行此处
        log.error("hystrix execute exception:", throwable);
        exchange.getAttributes().put(Constants.CLIENT_RESPONSE_RESULT_TYPE, ResultEnum.ERROR.getName());
        chain.execute(exchange);
    }).then();
}
image.png

onCompleted:onNext/onError完成之后最后回调

onError:当产生异常时回调

onNext:获取结果后回调

在fetchCommand方法,用于生成是信号量模式还是线程池模式的Command

image.png

HystrixHandle中给了ExecutionIsolationStrategy默认信号量的默认值

image.png

六、小结

  • 日拱一卒
  • 疑问:Hystrix已经停止维护了,真实项目使用此插件是否存在安全隐患?

你可能感兴趣的:(soul从入门到放弃11--浅入浅出Hystrix插件)