soul 源码分析 —— 插件解析之sentinel插件

sentinel流控设置

在这里插入图片描述

sentinel降级的设置

在这里插入图片描述

对应soul中sentinel插件的设置

在这里插入图片描述
规则说明:

流控:
是否开启流控(1或0) :是否开启sentinel的流控
阈值类型 : QPS 或线程数
流控效果 : 快速失效、Warm Up、排队等待
单机阈值 : 设置单机阈值数

熔断:
是否开启熔断(1或0) :是否开启sentinel熔断。
熔断降级策略: RT、异常比例、异常数
熔断阈值:阈值(RT数值)
熔断时间窗口: 降级的时间,单位为 s。
熔断URI: 熔断后的降级uri

SentinelPlugin源码解析

请求进入到SentinelPlugin的核心方法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;
        // 资源名(选择ID_规则名称),sentinel通过资源名来控制限流熔断
        String resourceName = SentinelRuleHandle.getResourceName(rule);
        // 获取限流降级规则对象
        SentinelHandle sentinelHandle = GsonUtils.getInstance().fromJson(rule.getHandle(), SentinelHandle.class);
        // SentinelReactorTransformer:对流控和熔断进行 响应式监控
        return chain.execute(exchange).transform(new SentinelReactorTransformer<>(resourceName)).doOnSuccess(v -> {
            // 处理成功,放行
            // 处理出错,输出错误
            if (exchange.getResponse().getStatusCode() != HttpStatus.OK) {
                HttpStatus status = exchange.getResponse().getStatusCode();
                exchange.getResponse().setStatusCode(null);
                throw new SentinelFallbackException(status);
            }
        }).onErrorResume(throwable -> sentinelFallbackHandler.fallback(exchange, UriUtils.createUri(sentinelHandle.getFallbackUri()), throwable));
    }

此方法做了如下操作:
1)将后台设置的降级规则转为SentinelHandle对象

@Getter
@Setter
@EqualsAndHashCode
public class SentinelHandle {
    // 是否启用流控
    private Integer flowRuleEnable = Constants.SENTINEL_ENABLE_FLOW_RULE;
    // 阈值类型
    private Integer flowRuleGrade = Constants.SENTINEL_QPS_FLOW_GRADE;
    // 单机阈值
    private Integer flowRuleCount;
    // 流控效果(快速失效、Warm Up、排队等待)
    private Integer flowRuleControlBehavior = Constants.SENTINEL_FLOW_REJECT;
    // 是否启用熔断降级
    private Integer degradeRuleEnable = Constants.SENTINEL_ENABLE_DEGRADE_RULE;
    // 降级策略(RT、异常比例、异常数)
    private Integer degradeRuleGrade = Constants.SENTINEL_RESPONSE_RULE_GRADE;
    // RT数
    private Integer degradeRuleCount;
    // 时间窗口
    private Integer degradeRuleTimeWindow;
    // 自定义异常路径
    private String fallbackUri;
}

2)获取资源名,对该资源进行降级规则设置处理
资源名:选择ID_规则名称
使用com.alibaba.csp.sentinel.adapter.reactor.SentinelReactorTransformer对该资源进行流控、熔断的设置处理

 // SentinelReactorTransformer:对流控和熔断进行 响应式监控
 return chain.execute(exchange).transform(new SentinelReactorTransformer<>(resourceName)).doOnSuccess(v -> {
            // 处理成功,放行
            // 处理出错,输出错误
            if (exchange.getResponse().getStatusCode() != HttpStatus.OK) {
                HttpStatus status = exchange.getResponse().getStatusCode();
                exchange.getResponse().setStatusCode(null);
                throw new SentinelFallbackException(status);
            }
        }).onErrorResume(throwable -> sentinelFallbackHandler.fallback(exchange, UriUtils.createUri(sentinelHandle.getFallbackUri()), throwable));

如果出错:调用SentinelFallbackHandlerfallback方法

default Mono<Void> fallback(ServerWebExchange exchange, URI uri, Throwable t) {
        if (Objects.isNull(uri)) {
            return generateError(exchange, t);
        }
        DispatcherHandler dispatcherHandler = SpringBeanUtils.getInstance().getBean(DispatcherHandler.class);
        ServerHttpRequest request = exchange.getRequest().mutate().uri(Objects.requireNonNull(uri)).build();
        ServerWebExchange mutated = exchange.mutate().request(request).build();
        return dispatcherHandler.handle(mutated);
    }

先判断是否有熔断后的降级uri处在(后台设置),如果不存在,调用generateError方法,否则调用uri返回错误信息
generateError方法的处理

public Mono<Void> generateError(final ServerWebExchange exchange, final Throwable throwable) {
        Object error;
        // 降级
        if (throwable instanceof DegradeException) {
            exchange.getResponse().setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);
            error = SoulResultWrap.error(SoulResultEnum.SERVICE_RESULT_ERROR.getCode(), SoulResultEnum.SERVICE_RESULT_ERROR.getMsg(), null);
        } else if (throwable instanceof FlowException) { // 限流
            exchange.getResponse().setStatusCode(HttpStatus.TOO_MANY_REQUESTS);
            error = SoulResultWrap.error(SoulResultEnum.TOO_MANY_REQUESTS.getCode(), SoulResultEnum.TOO_MANY_REQUESTS.getMsg(), null);
        } else if (throwable instanceof BlockException) { // 阻塞
            exchange.getResponse().setStatusCode(HttpStatus.TOO_MANY_REQUESTS);
            error = SoulResultWrap.error(SoulResultEnum.SENTINEL_BLOCK_ERROR.getCode(), SoulResultEnum.SENTINEL_BLOCK_ERROR.getMsg(), null);
        } else {
            return Mono.error(throwable);
        }
        return WebFluxResultUtils.result(exchange, error);
    }

此方法是针对降级、限流、阻塞的默认处理。
此致,整个请求结束,进行到下一个插件

流控验证

设置如下:
在这里插入图片描述
正常访问:
在这里插入图片描述
快速点两下:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值