SpringCloud Alibaba之Sentinel的流控规则简介

所有代码都在github上:https://github.com/demonruin/cloud2020/tree/master

一、流控规则 :流量限制控制规则

Sentinel-dashboard中的流控规则菜单项:

  • 资源名:唯一名称,默认请求路径
  • 针对来源: Sentine可以针对调用者进行限流,填写微服务名,默认default (不区分来源)
  • 阈值类型/单机阈值:
    •  QPS (每秒钟的请求数量) :当调用该api的QPS达到阈值的时候,进行限流
    •  线程数:当调用该api的线程数达到阈值的时候,进行限流
  • 是否集群:不需要集群
  • 流控模式:
    •  直接: api达到限流条件时,直接限流
    •  关联:当关联的资源达到阈值时,就限流自己
    •  链路:只记录指定链路上的流量(指定资源从入口资源进来的流量,如果达到阈值,就进行限流) [ api级别的针对来源]
  • 流控效果:
    •   快速失败:直接失败,抛异常
    •   Warm Up:根据codeFactor (冷加载因子,默认3)的值,从阈值/codeFactor, 经过预热时长,才达到置的QPS阈值
    •  排队等待:匀速排队,让请求以匀速的速度通过,阈值类型必须设置为QPS,否则无效

二、流控模式:

配置流控模式有两种方法:

1、在簇点链路中找到对应的资源名(即访问路径---唯一的),然后操作添加 流控

2、在流控规则里面  新增流控规则 填写 资源名等配置,和1操作等同

下面对不同的模式进行测试:

1、default模式:

就是直接-->快速失败模式  也即系统默认模式,进行测试设置,查看测试结果:设置default、QPS类型,单机阈值为1(即1秒请求一次),流控模式为直接、流控效果为快速失败。

测试结果:当每秒请求一次的时候,正常响应结果,当每秒请求次数超过一次的时候,会出现快速失败结果Blocked by Sentinel (flow limiting),如图下:

这种是直接调用默认的报错方法,应该还会有自定义的fallback方法进行我们自己的后续处理,后续再讲这部分~

当我们将阈值类型 改为 线程数的时候,就没有下面的流控效果配置了:

此时的意思和QPS就不太一样了,

QPS是直接让一波请求过来的时候只放一个进来,其他的就快速失败;

而线程数设置是指接口就一个能进行处理请求,把请求全部放进来,等处理请求处理不过来的时候,就快速失败。

测试:在testA接口中添加睡眠一段时间,进行测试

 @GetMapping("/testA")
    public String testA()
    {
        try {TimeUnit.MILLISECONDS.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}
        return "------testA";
    }

开启两个窗口,进行来回切换快速刷新来访问接口testA来测试能不能快速失败

很不幸,我测试了好几次,都不能快速失败,不知道啥情况额·可能是机子性能有点好哈哈~~~有点尴尬

2、关联模式:

当关联的资源达到阈值时,就限流自己

当与A关联的资源B达到阈值后,就限流自己A
B惹事,A挂了,下面进行设置关联模式

下面通过postman模拟并发密集访问testB,利用collections来模拟

此时,请求testA接口还能访问成功,当我们通过postman请求testB接口后,再访问testA发现已经出现快速失败了

当postman中的testB接口访问完成以后,再来看testA接口,发现已经恢复正常了!

测试过程:访问testB成功-->postman里新建多线程集合组-->将访问地址添加进新线程组-->Run-->大批量线程高并发访问B,导致A失效了

就相当于这种业务场景:下订单支付,支付系统已经满载了,此时就会直接让下订单服务快速失败,等支付系统恢复后,下订单服务恢复正常~

3、链路模式:

未完待续~~

 

 

三、流控效果:

流量控制官网:https://github.com/alibaba/Sentinel/wiki/%E6%B5%81%E9%87%8F%E6%8E%A7%E5%88%B6

1、直接拒绝 :直接->快速失败(默认的流控处理)

直接拒绝RuleConstant.CONTROL_BEHAVIOR_DEFAULT)方式是默认的流量控制方式,当QPS超过任意规则的阈值后,新的请求就会被立即拒绝,拒绝方式为抛出FlowException。这种方式适用于对系统处理能力确切已知的情况下,比如通过压测确定了系统的准确水位时

直接失败,抛出异常,Blocked by Sentinel (flow limiting)

源码位置:com.alibaba.csp.sentinel.slots.block.flow.controller.DefaultController

2、预热

Warm Up(RuleConstant.CONTROL_BEHAVIOR_WARM_UP)方式,即预热/冷启动方式。当系统长期处于低水位的情况下,当流量突然增加时,直接把系统拉升到高水位可能瞬间把系统压垮。通过"冷启动",让通过的流量缓慢增加,在一定时间内逐渐增加到阈值上限,给冷系统一个预热的时间,避免冷系统被压垮。详细文档可以参考 流量控制 - Warm Up 文档,具体的例子可以参见 WarmUpFlowDemo

当流量突然增大的时候,我们常常会希望系统从空闲状态到繁忙状态的切换的时间长一些。即如果系统在此之前长期处于空闲的状态,我们希望处理请求的数量是缓步的增多,经过预期的时间以后,到达系统处理请求个数的最大值。Warm Up(冷启动,预热)模式就是为了实现这个目的的。这个场景主要用于启动需要额外开销的场景,例如建立数据库连接等。

公式:阈值除以coldFactor(默认值为3),经过预热时长后才会达到阈值

默认coldFactor为3,即请求QPS从threshold/3开始,经预热时长逐渐升至设定的QPS阈值。

限流-冷启动官网https://github.com/alibaba/Sentinel/wiki/%E9%99%90%E6%B5%81---%E5%86%B7%E5%90%AF%E5%8A%A8

源码位置:com.alibaba.csp.sentinel.slots.block.flow.controller.WarmUpController

下面进行预热配置演示testB

案例:阀值为10+预热时长设置5秒。
系统初始化的阀值为10 / 3约等于3,即阀值刚开始为3;然后过了5秒后阀值才慢慢升高恢复到10

注意:因为我机子速度快的原因,5s预热时长我看不出效果,所以我将预热时长改为了10s,所以进行测试会出现正常结果:

当请求一次testB的时候,能正常响应,等进行快速刷新请求testB的时候,会时不时的出现 快速失败界面,然后等达到预热时长5s后,再访问就不会出现快速失败了,说明已经预热完成,能处理并发请求了

应用场景:秒杀系统在开启的瞬间,会有很多流量上来,很有可能把系统打死,预热方式就是把为了保护系统,可慢慢的把流量放进来,慢慢的把阀值增长到设置的阀值。

 

3、匀速排队

匀速排队(RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER)方式会严格控制请求通过的间隔时间,也即是让请求以均匀的速度通过,对应的是漏桶算法。详细文档可以参考 流量控制 - 匀速器模式,具体的例子可以参见 PaceFlowDemo

该方式的作用如下图所示:

 

这种方式主要用于处理间隔性突发的流量,例如消息队列。想象一下这样的场景,在某一秒有大量的请求到来,而接下来的几秒则处于空闲状态,我们希望系统能够在接下来的空闲期间逐渐处理这些请求,而不是在第一秒直接拒绝多余的请求。

源码位置:com.alibaba.csp.sentinel.slots.block.flow.controller.RateLimiterController

演示:设置QPS,这里只能是QPS才有匀速排队效果,设置阈值为1QPS,超时时间为20s

我们再通过postman模拟请求,通过后台查看是否有排队效果

启动访问,后台打印的日志却是一秒一次,说明我们的匀速排队流控设置成功了,不管前台访问多么高,到了我这里流控就是排队,1QPS来进行响应,表示设置 匀速排队成功

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章