hystrix插件是用来做熔断的,服务熔断就是当A服务去调用B服务,如果A服务迟迟没有收到B服务的响应,那么就终断当前的请求,而不是一直等待下去,一直等待下去的结果就是拖垮其它的服务。当系统发生熔断的时候,我们还要去监控B服务,当B服务恢复正常使用时,A服务就发起重新调用的请求。

首先在 soul-bootstrap 添加依赖

<dependency>
    <groupId>org.dromara</groupId>
    <artifactId>soul-spring-boot-starter-plugin-hystrix</artifactId>
    <version>${project.version}</version>
</dependency>

启动 soul-admin,soul-bootstrap,soul-examples-http ,登录 soul-admin 开启 hystrix 插件。在 hystrix 菜单配置选择器和规则,这里选择器规则匹配方式和 divide 插件一致。

这几个参数官方文档也有解释。

虽然写的很清楚,但对于没用过熔断的人来说好难懂啊。网上查了下才了解到这个具体意思。

错误百分比阀值默认值 50,如果一段时间内有100个请求,其中有54个超时或者异常,那么这段时间内的错误率是54%,大于了50,这种情况下会触发熔断器打开。

跳闸最小请求数量默认值20,意思是至少有20个请求才进行 错误百分比阀值 的计算,就是说如果你只来了19个请求,即使全是失败的,但没到二十个,就不会打开熔断器。

跳闸休眠时间(ms) :当熔断器开启一段时间之后,比如5000ms,会尝试放过去一部分流量进行试探,确定依赖服务是否恢复。

    protected Mono<Void> doExecute(final ServerWebExchange exchange, final SoulPluginChain chain, final SelectorData selector, final RuleData rule) {
        final SoulContext soulContext = exchange.getAttribute(Constants.CONTEXT);
        assert soulContext != null;
        //把这些参数组装到 HystrixHandle 类
        final HystrixHandle hystrixHandle = GsonUtils.getInstance().fromJson(rule.getHandle(), HystrixHandle.class);
        if (StringUtils.isBlank(hystrixHandle.getGroupKey())) {
            hystrixHandle.setGroupKey(Objects.requireNonNull(soulContext).getModule());
        }
        if (StringUtils.isBlank(hystrixHandle.getCommandKey())) {
            hystrixHandle.setCommandKey(Objects.requireNonNull(soulContext).getMethod());
        }
        //构建 command 类
        Command command = fetchCommand(hystrixHandle, exchange, chain);
        return Mono.create(s -> {
            Subscription sub = command.fetchObservable().subscribe(s::success,
                    s::error, s::success);
            s.onCancel(sub::unsubscribe);
            if (command.isCircuitBreakerOpen()) {
                //熔断开启,记录日志
                log.error("hystrix execute have circuitBreaker is Open! groupKey:{},commandKey:{}", hystrixHandle.getGroupKey(), hystrixHandle.getCommandKey());
            }
        }).doOnError(throwable -> {
            log.error("hystrix execute exception:", throwable);
            exchange.getAttributes().put(Constants.CLIENT_RESPONSE_RESULT_TYPE, ResultEnum.ERROR.getName());
            chain.execute(exchange);
        }).then();
    }

    private Command fetchCommand(final HystrixHandle hystrixHandle, final ServerWebExchange exchange, final SoulPluginChain chain) {
        //soul指定了默认的隔离策略是 SEMAPHORE 
        if (hystrixHandle.getExecutionIsolationStrategy() == HystrixIsolationModeEnum.SEMAPHORE.getCode()) {
            return new HystrixCommand(HystrixBuilder.build(hystrixHandle),
                exchange, chain, hystrixHandle.getCallBackUri());
        }
        return new HystrixCommandOnThread(HystrixBuilder.buildForHystrixCommand(hystrixHandle),
            exchange, chain, hystrixHandle.getCallBackUri());
    }

这里配置好了后,hystrix插件就自动帮我们做熔断的控制了。