soul源码阅读 soul插件之hystrix插件

本文主要介绍了Soul框架中的Hystrix插件,作为流量熔断的核心实现,HystrixPlugin继承自AbstractSoulPlugin,并实现了SoulPlugin接口。详细探讨了HystrixPlugin的execute方法及断路器逻辑,包括插件的优先级设置以及关键配置如跳闸最小请求数量、错误百分比阀值、最大并发量和跳闸休眠时间等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

hystrix插件

根据官网的介绍,hystrix插件是网关用来对流量进行熔断的核心实现。查看代码可以发现,

  • HystrixPlugin extends AbstractSoulPlugin
  • AbstractSoulPlugin implements SoulPlugin

SoulPlugin 是一个接口,接口定义了4个方法execute,getOrder,named,skip。execute是执行方法,getorder是获取优先级,named获取的是插件名,skip方式是判断是否跳过该插件。
AbstractSoulPlugin是插件的抽象类,以下17个是继承的类。HystrixPlugin是其中一个。

以下是AbstractSoulPlugin.execute方法。

public Mono<Void> execute(final ServerWebExchange exchange, final SoulPluginChain chain) {
		// 获取插件名称
    String pluginName = named();
    // 根据插件名获取该插件的基本数据,如 PluginData(id=9, name=hystrix, config=null, role=0, enabled=true)
    final PluginData pluginData = BaseDataCache.getInstance().obtainPluginData(pluginName);
  	// 要在 soul-admin 中将插件打开,否则web请求不会被此插件处理 
    if (pluginData != null && pluginData.getEnabled()) {
      	// 选择器数据
        final Collection<SelectorData> selectors = BaseDataCache.getInstance().obtainSelectorData(pluginName);
        if (CollectionUtils.isEmpty(selectors)) {
            return handleSelectorIsNull(pluginName, exchange, chain);
        }
        final SelectorData selectorData = matchSelector(exchange, selectors);
        if (Objects.isNull(selectorData)) {
            return handleSelectorIsNull(pluginName, exchange, chain);
        }
        selectorLog(selectorData, pluginName);
      	// 规则列表
        final List<RuleData> rules = BaseDataCache.getInstance().obtainRuleData(selectorData.getId());
        if (CollectionUtils.isEmpty(rules)) {
            return handleRuleIsNull(pluginName, exchange, chain);
        }
        RuleData rule;
        if (selectorData.getType() == SelectorTypeEnum.FULL_FLOW.getCode()) {
            //get last
            rule = rules.get(rules.size() - 1);
        } else {
            rule = matchRule(exchange, rules);
        }
        if (Objects.isNull(rule)) {
            return handleRuleIsNull(pluginName, exchange, chain);
        }
        ruleLog(rule, pluginName);
      	// 熔断逻辑 
        return doExecute(exchange, chain, selectorData, rule);
    }
    return chain.execute(exchange);
}

doExecute()方法中的断路器是判断熔断的关键:

@Override
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;
  	// 从当前web请求匹配上的规则取出熔断配置
    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())) {
      	// 没有配置 ‘命令Key’ 时,设置一个默认的
        hystrixHandle.setCommandKey(Objects.requireNonNull(soulContext).getMethod());
    }
    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();
}

在PluginEnum中定义了code(优先级),role,和name。这里设置了HYSTRIX,SENTINEL,RESILIENCE4J的优先级都为45,数字越小优先级越高。

    /**
     * Hystrix plugin enum.
     */
    HYSTRIX(45, 0, "hystrix"),

    /**
     * Sentinel plugin enum.
     */
    SENTINEL(45, 0, "sentinel"),

    /**
     * Resilence4J plugin enum.
     */
    RESILIENCE4J(45, 0, "resilience4j"),

Hystrix处理详解:

根据官网的解释,可以看到有如下配置。

  • 跳闸最小请求数量 :最小的请求量,至少要达到这个量才会触发熔断

  • 错误百分比阀值 : 这段时间内,发生异常的百分比。

  • 最大并发量 : 最大的并发量

  • 跳闸休眠时间(ms) :熔断以后恢复的时间。

  • 分组Key: 一般设置为:contextPath

  • 命令Key: 一般设置为具体的 路径接口。

具体界面如下图所示

image-20210130001240157

这里附上官方文档flow chart

在这里插入图片描述

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值