流控规则
注:Sentinel的监控页⾯⼀开始是没有东西,需要对监控的服务发起请求后才会出现
流量控制(flow control)
原理是监控应⽤流量的 QPS 或并发线程数等指标,当达到指定的阈值时对流量进⾏控制,以避免被瞬时的流量⾼峰冲垮,从⽽保障应⽤的⾼可⽤性;
两种规则
基于统计并发线程数的流量控制
并发数控制⽤于保护业务线程池不被慢调⽤耗尽
Sentinel 并发控制不负责创建和管理线程池,⽽是简单统计当前请求上下⽂的线程数⽬(正在执⾏的调⽤数⽬); 如果超出阈值,新的请求会被⽴即拒绝,效果类似于信号量隔离;
基于统计QPS的流量控制
当 QPS 超过某个阈值的时候,则采取措施进⾏流量控制; 控制⾯板
资源名:唯⼀名称,默认请求路径
针对来源:Sentinel可以针对调⽤者进⾏限流,填写微服务名,指定对哪个微服务进⾏限流 ,默认default(不区分来源,全部限制)阈值类型/单机阈值:
QPS(每秒钟的请求数量):当调⽤该接⼝的QPS达到了阈值的时候,进⾏限流;线程数:当调⽤该接⼝的线程数达到阈值时,进⾏限流是否集群:不需要集群流控模式:
直接:接⼝达到限流条件时,直接限流关联:当关联的资源达到阈值时,就限流⾃⼰
链路:只记录指定链路上的流量(指定资源从⼊⼝资源进来的流量,如果达到阈值,就可以限流)[api级别的针对来源]流控效果
快速失败:直接失败,就异常
Warm Up:根据codeFactor(冷加载因⼦,默认为3)的值,即请求 QPS 从 threshold / 3 开始,经预热时长逐渐升⾄设定的 QPS 阈值 []
直接快速失败
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\ public CommonResult getOrder() {
return new CommonResult(0, String.valueOf(new Random().nextInt())); }
public CommonResult handleException(BlockException ex) { return new CommonResult(-1,
ex.getClass().getCanonicalName() + \"\服务不可⽤\"); }}
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 进⾏链路限流; []
@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不起作⽤,参考[]
流量效果
快速失败
直接拒绝(RuleConstant.CONTROL_BEHAVIOR_DEFAULT)⽅式是默认的流量控制⽅式,当QPS超过任意规则的阈值后,新的请求就会被⽴即拒绝,拒绝⽅式为抛出FlowException。这种⽅式适⽤于对系统处理能⼒确切已知的情况下,⽐如通过压测确定了系统的准确⽔位时。具体的例⼦参见 。[]
预热 Warm Up
Warm Up(RuleConstant.CONTROL_BEHAVIOR_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 []
因篇幅问题不能全部显示,请点此查看更多更全内容