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();
        }

    }

三、自问自答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);
            }
        }
    }
}

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);
        }
    }
}

四、总结

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

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

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

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

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
sentinel限流的实战中,我们可以通过以下步骤来实现: 1. 首先,了解sentinel的三大功能:限流、降级和系统保护。 2. 引入sentinel的依赖,并配置好项目的相关信息,如应用名称、端口等。 3. 在需要进行限流的代码块或方法上,使用sentinel提供的注解或API进行限流配置。可以设置限流的阈值、流控模式等。 4. 运行项目,并观察sentinel的日志,可以通过日志来查看运行过程中的限流状态,了解规则的详细作用。 总结起来,sentinel限流的实战包括引入依赖、配置相关信息,使用注解或API进行限流配置,观察日志来查看限流状态。通过这些步骤,我们可以实现对代码块或方法的限流控制。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [Sentinel 实战-限流篇](https://blog.csdn.net/weixin_34194087/article/details/91439754)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *3* [Sentinel限流应用实践](https://blog.csdn.net/m0_64736092/article/details/123213082)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

子涵先生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值