1. Sentinel流控规则简介
这里的流控指的是“流量控制”,进一步解释说明:
-
资源名:唯一名称,默认请求路径。
-
针对来源:Sentinel可以针对调用者进行限流,填写微服务名,默认default(不区分来源)。
-
阈值类型/单机阈值:
- QPS(每秒钟的请求数量)︰当调用该API的QPS达到阈值的时候,进行限流。
- 线程数:当调用该API的线程数达到阈值的时候,进行限流。
-
是否集群:不需要集群
-
流控模式:
- 直接:API达到限流条件时,直接限流
- 关联:当关联的资源达到阈值时,就限流当前资源
- 链路:只记录指定链路上的流量(指定资源从入口资源进来的流量,如果达到阈值,就进行限流)【API级别的针对来源】。
-
流控效果:
- 快速失败:直接失败,抛出异常
- Warm up:根据Code Factor的值(冷加载因子,默认3),从阈值/code Factor,经过预热时长,才达到设置的QPS阈值。
- 排队等待:匀速排队,让请求以匀速通过,阈值类型必须设置为QPS,否则无效。
2. Sentinel流控规则介绍
2.1. 模式一:QPS直接快速失败
规则设置: QPS -> 直接 -> 快速失败 (sentinel的默认设置)
配置说明: 以上设置表示是对/testA进行访问流量监控,1秒钟内允许最多查询1次,若超过次数1,则直接->快速失败,抛出默认错误。
测试流控效果: 可以在浏览器快速多次访问请求地址http://localhost:8401/testA,返回页面 Blocked by Sentinel (flow limiting),访问量下降后自动恢复访问。
2.2. 模式二:并发线程数直接失败
线程数:当调用该API的线程数达到阈值的时候,进行限流。可以用JMeter进行并发线程测试
2.3. 模式三:QPS关联快速失败
流控模式-关联:当前资源可以将一个服务访问接口作为关联资源,当被关联的资源达到预定的阈值时,对自身进行限流。这样设计的目的是为了在testA/B在争抢资源时,保证B可以正常运行。
1. 设置testA的流控规则,将testB设置为testA的关联资源。
以下设置表示:testB为testA的关联资源,当关联资源testB的QPS(每秒的访问量)大于1时,testA就会进行流控,效果为快速失败。
2. 使用Postman进行并发测试,密集访问testB
2.1. 新建一个多线程集合,并添加testB请求。
2.2. 请求添加完成后,为请求集合添加一个访问迭代器,循环调用testB请求。
3. 启动postman循环调用,此时再访问/testA,发现服务中断了。
3. Sentinel流控-链路
NodeSelectorSlot 中记录了资源之间的调用链路,这些资源通过调用关系,相互之间构成一棵调用树。这棵树的根节点是一个名字为 machine-root 的虚拟节点,调用链的入口都是这个虚节点的子节点。
一棵典型的调用树如下图所示:
上图中来自入口 Entrance1 和 Entrance2 的请求都调用到了资源 NodeA,Sentinel 允许只根据某个入口的统计信息对资源限流。比如我们可以设置 FlowRule.strategy 为 RuleConstant.CHAIN,同时设置 FlowRule.ref_identity 为 Entrance1 来表示只有从入口 Entrance1 的调用才会记录到 NodeA 的限流统计当中,而对来自 Entrance2 的调用漠不关心。调用链的入口是通过 API 方法 ContextUtil.enter(name) 定义的。
4. Sentinel流控-预热
Warm Up(RuleConstant.CONTROL_BEHAVIOR_WARM_UP)方式,即预热/冷启动方式。当系统长期处于低水位的情况下,当流量突然增加时,直接把系统拉升到高水位可能瞬间把系统压垮。通过"冷启动",让通过的流量缓慢增加,在一定时间内逐渐增加到阈值上限,给冷系统一个预热的时间,避免冷系统被压垮。详细文档可以参考 流量控制 - Warm Up 文档,具体的例子可以参见 WarmUpFlowDemo。
通常冷启动的过程系统允许通过的 QPS 曲线如下图所示:
默认coldFactor为3,即请求QPS 从 threshold / 3开始,经预热时长逐渐升至设定的QPS阈值。
源码可以查看: com.alibaba.csp.sentinel.slots.block.flow.controller.WarmUpController
流控规则测试:QPS-直接-WarmUp
以上配置表示:
系统在开始的时候会将单机阈值控制在3(10 设置的单机阈值/3 默认的冷却因子),等经过预热时长5秒后,再将单机阈值提高到10。当前5秒每秒的请求大于3时,系统会直接抛出异常,后5秒则变为10.
5. Sentinel流控-排队等待
匀速排队(RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER)方式会严格控制请求通过的间隔时间,也即是让请求以均匀的速度通过,对应的是漏桶算法。详细文档可以参考 流量控制 - 匀速器模式,具体的例子可以参见 PaceFlowDemo。
这种方式主要用于处理间隔性突发的流量,例如消息队列。想象一下这样的场景,在某一秒有大量的请求到来,而接下来的几秒则处于空闲状态,我们希望系统能够在接下来的空闲期间逐渐处理这些请求,而不是在第一秒直接拒绝多余的请求。
5.1. 模式一:QPS直接排队等待
匀速排队,让请求以均匀的速度通过,阀值类型必须设成QPS,否则无效。
以上设置表示:/testB每秒允许1次请求,超过的话就排队等待,等待的超时时间为20000毫秒。
5.2. 使用postman进行测试
postman压测设置:
因为portman不能进行并发测试,我们这里只测试下,排队等待的匀速通过情况。超时请求失败可以使用jmeter进行并发请求测试。
设置请求集合的迭代请求为20次,每100毫秒请求一次。也就是说20次请求会在2秒内执行完成。
5.3. 启动迭代请求,观察后台打印:
我们可以看到本应失败的请求,在排队等待策略下,全部已1秒一次的匀速方式,成功访问。
注意:匀速排队模式暂时不支持 QPS > 1000 的场景。