Sentinel流控规则
流控规则基本介绍
名词解释
- 资源名:唯一名称,默认请求路径
- 针对来源:Sentinel可以针对请求来源进行限流,填写微服务名称,默认default不区分来源
- 阈值类型/单机阈值:
1.QPS(每秒请求数):当API每秒请求数量达到阈值,则进行限流
2.线程数:当请求API的数量达到一定数量则进行限流 - 是否集群:当前不需要集群
- 流控模式
1.直接:当访问API数量达到阈值,则直接限流
2.关联:当访问关联资源达到阈值,则限流自己
3.链路:只记录指定路径上的流量(指定资源从资源入口来的流量达到阈值,则直接限流)(API级别的针对来源) - 流控效果
1.快速失败:直接失败,抛异常
2.Wam Up:根据codeFactor(冷加载因子,默认3)的值,从阈值/codeFacotor,经过预热时长,才达到设置的QPS阈值
3.排队等待:匀速排队,让请求以匀速的速度通过,阈值类型必须设置为QPS,否则无效
具体操作
新增流控
QPS直接失败案例
- 添加有两种方式,可以直接在流控规则选项中添加,也可以在簇点链路中添加,一般会采取第二种方式
当我一秒内访问次数未达到阈值和达到阈值
线程数直接失败案例
- 刚才我们可以的设置是通过QPS(每秒钟请求的数量)来设置的限流规则,但是我们这里其实还有一个线程数,是什么意思那?
2.QPS和并发线程数规则详解
3.那我们要演示这种效果,我们就需要让一个线程再进来办理的时候需要0.8秒,但是这个时候后面的线程也在疯狂的访问,所以后面的线程就会不会生效。
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class FlowControllerEffectController {
@GetMapping("/warmup")
public String threads(){
try{
Thread.sleep(200);
}catch (InterruptedException e){
e.printStackTrace();
}
return "测试流控效果===热启动";
}
}
4.这个时候我们重启项目,然后重新通过访问warmup接口,通过两个网页(线程)来快速访问,这个时候我们来看效果,这里要注意,要重新添加流控规则。
关联
官方解释:当关联的资源达到阈值时,就限流自己。
通俗解释来说,比如那我们的程序,现在有testA接口和testB接口,当A关联的资源B达到阈值后,就限流自己,也就是B到达阈值,限流A本身。就好像我家孩子在外面打架,我来处理一样。换到程序里面来说比如一个电商系统中,支付系统达到阈值,就限流下订单系统。
具体演示
当关联资源**/test的qps阈值超时1时,就限流/warmup**的Rest访问地址,当关联资源到阈值后限制配置好的资源名
@RestController
public class FlowControllerEffectController {
@GetMapping("/warmup")
public String threads(){
return "测试流控效果===热启动warmup";
}
@GetMapping("/test")
public String threads1(){
try{
System.out.println(System.currentTimeMillis());
Thread.sleep(3000);
System.out.println(System.currentTimeMillis());
}catch (InterruptedException e){
e.printStackTrace();
}
return "测试流控效果===热启动test";
}
}
演示时,先请求/test接口,让/test有一个访问线程,达到线程阈值,然后再请求/warmup
链路流控模式
链路流控模式指的是,当从某个接口过来的资源达到限流条件时,开启限流。它的功能有点类似于针对 来源配置项,区别在于:针对来源是针对上级微服务,而链路流控是针对上级接口,也就是说它的粒度更细。
编写service,将里面的方法添加注解@SentinelResource,作为Sentinel资源
@Service
public class UserService {
@SentinelResource(value = "getUser")
public String getUser() {
return "获取用户信息";
}
}
写控制器接口,调用上面的service方法,两个接口之前没有其他限制
@GetMapping("/linkModle/test1")
public String test1(Integer userId){
userService.getUser();
return "成功";
}
@GetMapping("/linkModle/test2")
public String test2(Integer userId){
userService.getUser();
return "成功";
}
添加配置文件,不添加无法生效
我们需要将web-context-unify参数设置为false,将其配置为false既可以根据不同的URL进行链路限流,如果不配置将不会生效
添加阈值控制
正常访问
达到阈值的访问结果
没有设置链路的接口,虽然调用相同的service方法,不影响正常访问。
流控模式
当 QPS 超过某个阈值的时候,则采取措施进行流量控制。流量控制的效果包括以下几种:快速失败(直接拒绝)、Warm Up(预热)、匀速排队(排队等待)。对应 FlowRule 中的 controlBehavior 字段。
快速失败(默认)
当QPS超过任意规则的阈值后,新的请求就会被立即拒绝,拒绝方式为抛出FlowException这种方式适用于对系统处理能力确切已知的情况下,比如通过压测确定了系统的准确水位时。
Warm Up
它从开始阈值到最大QPS阈值会有一个缓冲阶段,一开始的阈值是最大QPS阈值的1/3,然后慢慢增长,直到最大阈值。
即预热/冷启动方式。当系统长期处于低水位的情况下,当流量突然增加时,直接把系统拉升到高水位可能瞬间把系统压垮。通过"冷启动",让通过的流量缓慢增加,在一定时间内逐渐增加到阈值上限,给冷系统一个预热的时间,避免冷系统被压垮。
冷加载因子: codeFactor 默认是3,即请求 QPS 从 threshold / 3 开始,经预热时长逐渐升至设定的 QPS 阈值。
通常冷启动的过程系统允许通过的 QPS 曲线如下图所示:
配置预热效果的阈值:
此配置相当于,刚开始阈值为10/3,在5秒内阈值增加到10
测试请求效果:
从监控可以看到,刚开始阈值低,通过的请求少,拒绝的请求多,随着时间推移,拒绝的请求减少,通过的请求增加,当达到5秒之后,只有通过的请求,没有拒绝的请求(每秒请求少于10,多于10的请求依然被拒绝)
排队等待
让请求以均匀的速度通过,单机阈值为每秒通过数量,其余的排队等待; 它还会让设置一个超时时间,当请求超过超时间时间还未处理,则会被丢弃。
该方式的作用如下图所示:
这种方式主要用于处理间隔性突发的流量,例如消息队列。想象一下这样的场景,在某一秒有大量的请求到来,而接下来的几秒则处于空闲状态,我们希望系统能够在接下来的空闲期间逐渐处理这些请求,而不是在第一秒直接拒绝多余的请求。
注意:匀速排队模式仅仅支持QPS,暂时不支持 QPS > 1000 的场景。【因为他的单位毫秒,所以最多是1秒通过一个,也就是1000qps】mu测试代码
@GetMapping("/warmup")
public String threads(){
log.info(Thread.currentThread().getName()+"warmup");
return "测试流控效果===热启动warmup";
}
设置阈值,排队模式:
排队模式,每秒处理一个请求,最多排队20秒,超过则不处理。
根据日志打印,可以看出来,虽然请求频繁,一秒超过1次,但是执行时间一秒一次,在请求结束后,依然在执行。
最好用工具快速执行。