正文
Sentinel流控规则
小程序:扫一扫查出行
【扫一扫了解最新限行尾号】
复制小程序
【扫一扫了解最新限行尾号】
复制小程序
流控规则
注:Sentinel的监控页面一开始是没有东西,需要对监控的服务发起请求后才会出现
资源名:唯一名称,默认请求路径
针对来源:
Sentinel
可以针对调用者进行限流,填写微服务名,指定对哪个微服务进行限流 ,默认default
(不区分来源,全部限制)阈值类型/单机阈值:
QPS(每秒钟的请求数量):当调用该接口的QPS达到了阈值的时候,进行限流;
线程数:当调用该接口的线程数达到阈值时,进行限流
是否集群:不需要集群
流控模式:
直接:接口达到限流条件时,直接限流
关联:当关联的资源达到阈值时,就限流自己
链路:只记录指定链路上的流量(指定资源从入口资源进来的流量,如果达到阈值,就可以限流)[api级别的针对来源]
流控效果
快速失败:直接失败,就异常
Warm Up:根据
codeFactor
(冷加载因子,默认为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#%E6%A6%82%E8%BF%B0]
https://github.com/alibaba/Sentinel/wiki/%E6%B5%81%E9%87%8F%E6%8E%A7%E5%88%B6#%E5%9F%BA%E4%BA%8Eqps%E5%B9%B6%E5%8F%91%E6%95%B0%E7%9A%84%E6%B5%81%E9%87%8F%E6%8E%A7%E5%88%B6
- 直接快速失败
QPS(每秒钟请求的数量):当调用该接口的QPS达到阈值的时候,进行限流
直接快速失败的效果:
- 线程数
当请求A过来访问该接口,该请求处理的很慢,还没有返回数据;此时请求B也过来访问该接口,这个时候处理请求B需要额外开启一个线程,请求B则会报错;
效果如下:
流控模式- 直接模式
Sentinel的流控模式代表的流控的方式,默认【直接】;
上面的/testA接口的流控,QPS单机阀值为1,代表每秒请求不能超出1,要不然就做流控处理,处理方式直接调用失败;
调用/testA,慢一点请求,正常返回;快速请求几次,超过阀值;接口返回了Blocked by Sentinel (flow limiting),代表被限流了;
- 关联模式
设置效果:当关联资源/testB的QPS阈值超过1时,就限流/testA的Rest的访问地址,当关联资源到资源阈值后限制配置好的资源名;
关联通俗点说就是,当关联的资源达到阀值,就限流自己;
应用场景: 比如支付接口达到阈值,就要限流下订单的接口,防止一直有订单
- 链路模式
链路流控模式指的是,当从某个接口过来的资源达到限流条件时,开启限流;它的功能有点类似于针对 来源配置项,区别在于:针对来源是针对上级微服务,而链路流控是针对上级接口,也就是说它的粒度 更细;
如下:
1.编写一个service
@Service
public class OrderServiceImpl implements OrderService { @Override
@SentinelResource(value = "getOrder", blockHandler = "handleException")
public CommonResult getOrder() {
return new CommonResult(0, String.valueOf(new Random().nextInt()));
} public CommonResult handleException(BlockException ex) {
return new CommonResult(-1,
ex.getClass().getCanonicalName() + "\t服务不可用");
}
}
2.在Controller声明两个方法
@Autowired
private OrderService orderService;@GetMapping("/test1")
public CommonResult test1() {
return orderService.getOrder();
}@GetMapping("/test2")
public CommonResult test2() {
return orderService.getOrder();
}
当流控规则配置了流控模式为链路时,发现当访问/test1
和/test2
接口都不能进行限流;
注意:
从1.6.3 版本开始, Sentinel Web filter默认收敛所有URL的入口context,因此链路限流不生效;
1.7.0 版本开始(对应Spring Cloud Alibaba的2.1.1.RELEASE),官方在CommonFilter
引入了WEB_CONTEXT_UNIFY
参数,用于控制是否收敛context;将其配置为 false 即可根据不同的URL 进行链路限流;[https://github.com/alibaba/Sentinel/issues/1213]
@Configuration
public class FilterContextConfig {
@Bean
public FilterRegistrationBean sentinelFilterRegistration() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new CommonFilter());
registration.addUrlPatterns("/*");
// 入口资源关闭聚合
registration.addInitParameter(CommonFilter.WEB_CONTEXT_UNIFY, "false");
registration.setName("sentinelFilter");
registration.setOrder(1);
return registration;
}
}
关于新版本web-context-unify
不起作用,参考[https://github.com/alibaba/Sentinel/issues/1313]
流量效果快速失败
直接拒绝(RuleConstant.CONTROL_BEHAVIOR_DEFAULT
)方式是默认的流量控制方式,当QPS超过任意规则的阈值后,新的请求就会被立即拒绝,拒绝方式为抛出FlowException
。这种方式适用于对系统处理能力确切已知的情况下,比如通过压测确定了系统的准确水位时。具体的例子参见 FlowQpsDemo。
[https://github.com/alibaba/Sentinel/wiki/%E6%B5%81%E9%87%8F%E6%8E%A7%E5%88%B6#%E7%9B%B4%E6%8E%A5%E6%8B%92%E7%BB%9D]
- 预热 Warm Up
快速失败
直接拒绝(RuleConstant.CONTROL_BEHAVIOR_DEFAULT
)方式是默认的流量控制方式,当QPS超过任意规则的阈值后,新的请求就会被立即拒绝,拒绝方式为抛出FlowException
。这种方式适用于对系统处理能力确切已知的情况下,比如通过压测确定了系统的准确水位时。具体的例子参见 FlowQpsDemo。
[https://github.com/alibaba/Sentinel/wiki/%E6%B5%81%E9%87%8F%E6%8E%A7%E5%88%B6#%E7%9B%B4%E6%8E%A5%E6%8B%92%E7%BB%9D]
Warm Up(RuleConstant.CONTROL_BEHAVIOR_WARM_UP
)方式,即预热/冷启动方式。当系统长期处于低水位的情况下,当流量突然增加时,直接把系统拉升到高水位可能瞬间把系统压垮。通过"冷启动",让通过的流量缓慢增加,在一定时间内逐渐增加到阈值上限,给冷系统一个预热的时间,避免冷系统被压垮。详细文档可以参考 流量控制 - Warm Up 文档,具体的例子可以参见 WarmUpFlowDemo。
[https://github.com/alibaba/Sentinel/wiki/%E6%B5%81%E9%87%8F%E6%8E%A7%E5%88%B6#warm-up]
根据codeFactor
(冷加载因子,默认为3)的值,即请求 QPS 从 threshold / 3
开始,经预热时长逐渐升至设定的 QPS 阈值 ;
系统初始化的默认阈值为10 / 3,即为3,也就是刚开始的时候阈值只有3,当经过5s后,阈值才慢慢提高到10;
源码:com.alibaba.csp.sentinel.slots.block.flow.controller.WarmUpController
应用场景:秒杀系统的开启瞬间,会有很多流量上来,很可能会把系统打挂,预热方式就是为了保护系统,可以慢慢的把流量放进来,慢慢的把阈值增长到设定值;
- 排队等待
匀速排队,让请求以均匀的速度通过,阈值类型必须设置成QPS
,否则无效;
设置的含义:/testA每秒1次请求,QPS大于1后,再有请求就排队,等待超时时间为20000毫秒;
这种方式主要用于处理间隔性突发的流量,例如消息队列。想象一下这样的场景,在某一秒有大量的请求到来,而接下来的几秒则处于空闲状态,我们希望系统能够在接下来的空闲期间逐渐处理这些请求,而不是在第一秒直接拒绝多余的请求。
源码:com.alibaba.csp.sentinel.slots.block.flow.controller.RateLimiterController
[https://github.com/alibaba/Sentinel/wiki/%E6%B5%81%E9%87%8F%E6%8E%A7%E5%88%B6#%E5%8C%80%E9%80%9F%E6%8E%92%E9%98%9F]