Sentinel:流控规则

9 篇文章 0 订阅
3 篇文章 0 订阅

上一篇文章,我们一起探讨了Sentinel流量控制的简单用法,本小节,我们一起探讨Sentinel的三种流控规则。

 

说到系统接口的限流,我们一般会想到用几种限流的算法,比如漏桶算法、令牌桶算法,在单机内,我们可以采用Guava中提供的API帮我们实现限流功能。而在分布式环境中,我们可以用Redis、MQ等中间件来实现限流的功能。

 

然而,Sentinel为我们提供了更加灵活的限流规则和策略,同时也支持单机和集群模式,方便我们根据不同的应用场景,选择不同的流控、限流的规则。

 

 常用的有如下三种:

  • 直接拒绝

  • 冷启动+预热

  • 匀速+排队

     

我们可以根据实际需求,来配置相应的流控规则。流控的重要属性如下:

字段说明默认值
resource资源名,是限流规则的作用对象 
count限流阈值 
grade限流阈值类型,QPS 模式(1)或并发线程数模式(0)QPS
limitApp流控针对的调用来源default,表示不区分调用来源
stragety调用关系限流策略:直接、链路、关联直连

controlBehavior

(本文重点讲解这个属性)

流控效果(直接拒绝/WarmUp/匀速+排队等待),不支持按调用关系限流直接拒绝
clusterMode是否是集群模式

ps:详细的工程创建,请参考笔者的这篇文章 Sentinel:流量控制

直接拒绝

我们都学过Java线程池的拒绝策略,所以通过名字,我们很容易就能想到,如果请求QPS达到了限流的阈值,那么直接将请求丢弃掉。示例代码如下:

public static void CONTROL_BEHAVIOR_DEFAULT(){
    String resource = "doSomeThing";
    List<FlowRule> rules = new ArrayList<>();
    FlowRule rule = new FlowRule();
    rule.setResource(resource);
    // QPS模式
    rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
    // 默认不区分调用分
    rule.setLimitApp("default");
    // 非集群模式
    rule.setClusterMode(false);
    // 直接拒绝效果
    rule.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_DEFAULT);
    // 限流阈值,允许最多每秒3个请求
    rule.setCount(3);
    rules.add(rule);
    FlowRuleManager.loadRules(rules);
    while(true){
        if(SphO.entry(resource)){
            try{
                System.out.println("正常执行");
            }finally {
                SphO.exit();
            }
        }else{
            System.out.println("被限流,直接拒绝");
        }
    }
}

根据代码中对限流规则的配置,通过while死循环模拟用户请求,sleep(200)模拟业务的耗时,如果每秒该方法的请求次数超过3次,那么直接将请求丢弃,也就是说,会打印出"被限流,直接拒绝"

我们从代码的执行结果中可以看出,QPS在2-4的范围内波动

正常执行
正常执行
正常执行
正常执行
被限流,直接拒绝
被限流,直接拒绝
正常执行
正常执行
正常执行
被限流,直接拒绝
正常执行
正常执行
被限流,直接拒绝
正常执行
被限流,直接拒绝
正常执行
正常执行
被限流,直接拒绝
正常执行
被限流,直接拒绝
正常执行

冷启动+预热(WarmUp)

当系统长期处于一个低负载的情况下,或服务刚刚启动,这种资源没有加载完成时,如果此时流量压过来,系统很有可能被冲垮。Sentinel也想到了这一点,它为我们提供了冷启动+预热模式,让通过的流量缓慢增加,在一定时间内达到我们配置的阈值上限,达到保护系统的作用。通常冷启动+预热允许通过请求的QPS曲线图如下所示:

示例代码如下


public static void CONTROL_BEHAVIOR_WARM_UP() {
    String resource = "doSomeThing";
    List<FlowRule> rules = new ArrayList<>();
    FlowRule rule = new FlowRule();
    rule.setResource(resource);
    // QPS模式
    rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
    // 冷启动+预热效果
    rule.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_WARM_UP);
    // 流控阈值
    rule.setCount(4);
    // 5s后达到我们配置的阈值上限
    rule.setWarmUpPeriodSec(5);
    rules.add(rule);
    FlowRuleManager.loadRules(rules);
    while (true) {
        if (SphO.entry(resource)) {
            try {
                System.out.println("正常执行");
            } finally {
                SphO.exit();
            }
        } else {
            System.out.println("被限流,直接拒绝");
        }
    }
}

同样,我们通过while死循环模拟用户请求,将controlBehavior设置为RuleConstant.CONTROL_BEHAVIOR_WARM_UP模式,流控阈值4,warmUpPeriodSec设置为5,表示通过的流量在5秒内缓慢增加,超过的请求直接丢弃,5秒后达到我们设置的阈值上限。

我们从代码运行输出的结果可以看到,系统刚启动时,被拒绝的请求占比较大,大约5s后,趋于稳定。


// 系统刚启动
正常执行
被限流,直接拒绝
被限流,直接拒绝
正常执行
被限流,直接拒绝
被限流,直接拒绝
被限流,直接拒绝
被限流,直接拒绝
正常执行
被限流,直接拒绝
被限流,直接拒绝
被限流,直接拒绝
被限流,直接拒绝
正常执行
// 大约5s后
正常执行
正常执行
正常执行
正常执行
被限流,直接拒绝
正常执行
正常执行
正常执行
正常执行
被限流,直接拒绝
正常执行

匀速+排队

我们可以把匀速+排队,理解为消息队列。流量压过来,把系统能承受范围之外的流量暂时存在消息队列中,在队列的消费方,根据消费方的处理能力缓慢消费,削峰填谷。

Sentinel中的匀速+排队方式会严格控制请求的通过时间,也即是让请求以均匀的速度通过。想象一下这样的场景,在某一秒有大量的请求到来,而接下来的几秒则处于空闲状态,我们希望系统能够在接下来的空闲期间逐渐处理这些请求,而不是在第一秒直接拒绝多余的请求。该方式的作用如下图所示:

示例代码如下:


public static void CONTROL_BEHAVIOR_RATE_LIMITER() {
    String resource = "doSomeThing";
    List<FlowRule> rules = new ArrayList<>();
    FlowRule rule = new FlowRule();
    rule.setResource(resource);
    // QPS模式
    rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
    // 匀速+排队效果
    rule.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER);
    // 限流阈值,最大每秒2次
    rule.setCount(2);
    // 最长排队等待时间:20s
    rule.setMaxQueueingTimeMs(2 * 1000);
    rules.add(rule);
    FlowRuleManager.loadRules(rules);
    while (true) {
        if (SphO.entry(resource)) {
            System.out.println("正常执行 " + System.currentTimeMillis());
        } else {
            System.out.println("被限流,直接拒绝");
        }
    }
}

为了方便演示,我们把限流阈值设置为2,通过死循环模拟用户请求,我们看输出结果中打印的时间信息,表明大约每秒会通过两个请求,每个请求大约500ms。


正常执行 1593772731264
正常执行 1593772731764
正常执行 1593772732266
正常执行 1593772732768
正常执行 1593772733264
正常执行 1593772733763
正常执行 1593772734262
正常执行 1593772734764
正常执行 1593772735264
正常执行 1593772735764
正常执行 1593772736267

另外,需要注意一点就是,要是匀速+排队效果生效的话,规则的限流类型一定是RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER。否则该效果不会生效。

 

好了,今天一起探讨的内容相对比较简单,从三个限流效果为大家演示了Sentinel强大的作用,为我们的系统保驾护航。在接下来的文章中,我会为大家一起探讨Sentinel更多的玩法,谢谢大家。

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值