当前位置:   article > 正文

Sentinel限流规则使用总结

sentinel限流规则

一、Sentinel限流/熔断规则

目前Sentinel支持以下五种限流/熔断规则:基于资源限流(FlowRule)、系统自适应限流(SystemRule)、系统熔断降级(DegradeRule)、热点参数限流(ParamFlowRule),sentinel还支持基于授权的限流(AuthorityRule),其父类为AbstractRule
在这里插入图片描述

二、网关限流原理

另外,Sentinel还支持网关限流,说到底就是Filter限流,控制限流资源范围。其实现原理为为Servlet添加了一个CommonFilter,doFilter方法如下:

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest sRequest = (HttpServletRequest)request;
        Entry urlEntry = null;

        try {
            String target = FilterUtil.filterTarget(sRequest);
            UrlCleaner urlCleaner = WebCallbackManager.getUrlCleaner();
            if (urlCleaner != null) {
                target = urlCleaner.clean(target);
            }

            if (!StringUtil.isEmpty(target)) {
                String origin = this.parseOrigin(sRequest);
                String contextName = this.webContextUnify ? "sentinel_web_servlet_context" : target;
                ContextUtil.enter(contextName, origin);
                //=============标记请求路径为资源 start===============
                if (this.httpMethodSpecify) {
                    String pathWithHttpMethod = sRequest.getMethod().toUpperCase() + ":" + target;
                    urlEntry = SphU.entry(pathWithHttpMethod, 1, EntryType.IN);
                } else {
                    urlEntry = SphU.entry(target, 1, EntryType.IN);
                }
                //=============标记请求路径为资源 end===============
            }

            chain.doFilter(request, response);
        } catch (BlockException var15) {
            HttpServletResponse sResponse = (HttpServletResponse)response;
            WebCallbackManager.getUrlBlockHandler().blocked(sRequest, sResponse, var15);
        } catch (ServletException | RuntimeException | IOException var16) {
            Tracer.traceEntry(var16, urlEntry);
            throw var16;
        } finally {
            if (urlEntry != null) {
                urlEntry.exit();
            }

            ContextUtil.exit();
        }

    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41

三、自问自答QA

  1. “资源”在一个系统中是唯一的吗?即不同接口上的资源名称可以重复吗?
    答:可以重复。resource相当于是一个分类,可以加在不同的接口上。

  2. 相同名称的rule可以加载成功吗?
    答:不可以,同一种类型的rule名称应保持唯一,规则会被放到一个Map中,key为resource名称。源码:com.alibaba.csp.sentinel.slots.block.flow.FlowRuleUtil#buildFlowRuleMap(java.util.List<com.alibaba.csp.sentinel.slots.block.flow.FlowRule>, com.alibaba.csp.sentinel.util.function.Function<com.alibaba.csp.sentinel.slots.block.flow.FlowRule,K>, com.alibaba.csp.sentinel.util.function.Predicate<com.alibaba.csp.sentinel.slots.block.flow.FlowRule>, boolean)

  3. 一个资源名称,在两个接口上一起使用时,限流统计规则是两个接口一起还是独立计算?
    答:独立计算。

  4. 是否允许通配的方式批量添加到controller层?
    答:可以。具体操作方法见第四节《网关限流》,其原理是基于Filter,请求进来的时候就被标记了资源。

  5. 资源定义的方式有很多种,建议通过注解。

  6. 通用异常处理方式?
    答:平台可以添加统一的异常处理,违反限流规则会抛出FlowException。源码追溯:com.alibaba.csp.sentinel.slots.block.flow.FlowRuleChecker#checkFlow

  7. 定义规则名称,与实际注解资源不匹配会报错吗?即注解使用了错误的规则。
    答:流控失败,且不会报错。

  8. 注解使用一定要放在Controller方法上吗?
    答:不一定,也可以在Service、工具类中,其本质为抛出了FlowException异常。

  9. 设置了全局范围资源点,且在接口上未定义其他资源,那么设置的资源规则、系统规则、降级规则还生效吗?
    答:1-资源规则不生效,检查过程是根据资源名称获取规则后再校验的,如图得到的规则未空,实际上是配置了资源规则的。

public void checkFlow(Function<String, Collection<FlowRule>> ruleProvider, ResourceWrapper resource,
                      Context context, DefaultNode node, int count, boolean prioritized) throws BlockException {
    if (ruleProvider == null || resource == null) {
        return;
    }
    Collection<FlowRule> rules = ruleProvider.apply(resource.getName());
    if (rules != null) {
        for (FlowRule rule : rules) {
            if (!canPassCheck(rule, context, node, count, prioritized)) {
                throw new FlowException(rule.getLimitApp(), rule);
            }
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

2-系统规则生效。com.alibaba.csp.sentinel.slots.system.SystemRuleManager#checkSystem
3-降级规则不生效。

public static void checkDegrade(ResourceWrapper resource, Context context, DefaultNode node, int count)
    throws BlockException {

    Set<DegradeRule> rules = degradeRules.get(resource.getName());
    if (rules == null) {
        return;
    }

    for (DegradeRule rule : rules) {
        if (!rule.passCheck(context, node, count)) {
            throw new DegradeException(rule.getLimitApp(), rule);
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

四、总结

Sentinel的官网文档已经很是完整了,此处仅是在下做的一些小总结。当然Sentinel的功能还是非常强大的,参数类型也众多,未能测试全面。大家在测试过程中可以使用测试工具JMeter进行测试。

顺便说两句,关于如何学习一个工具有两种思路:

  1. 第一种是基于测试,按照不同的用例来了解当前组件的功能;
  2. 第二种是看源码,了解工具的设计细节。

大家在学习的过程中,建议2种方式结合一下。通过测试了解基本功能,通过读源码来解释测试结果。这样双管齐下,便可进一步加深理解,学习软件背后的学习思路~
大家如有问题欢迎与我交流~

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/533291
推荐阅读
相关标签
  

闽ICP备14008679号