流控规则基本概念
- 资源名:唯一名称,默认请求路径
- 针对来源: Sentinel可以针对调用者进行限流,填写微服务名,默认 default(不区分来源)
- 阈值类型单机阈值:
- QPS(每秒钟的请求数量):当调用该api的QPS达到阈值的时候,进行限流
- 线程数:当调用该api的线程数达到阈值的时候,进行限流
- 是否集群:不需要集群
- 流控模式:
- 直接:api达到限流条件时,直接限流
- 关联:当关联的资源达到阈值时,就限流自己
- 链路:只记录指定链路上的流量(指定资源从入口资源进来的流量,如果达到阈值,就进行限流)【api级别的针对来源】
- 流控效果:
- 快速失败:直接失败,抛异常
- Warm Up:根据 codeFactor(冷加载因子,默认3)的值,从阈值 / codeFactor,经过预热时长,オ达到设置的QPS阈值
- 排队等待:匀速排队,让请求以匀速的速度通过,阈值类型必须设置为QPS,否则无效
流控模式
QPS直接失败
直接->快速失败:系统默认
配置及说明:
表示1秒内查询1次就ok,操作1次就直接—快速失败,报默认错误
思考
直接调用默认报错信息,技术方面OK
类似有一个fallback的兜底方法?
线程数直接报错
QPS和线程数控制的区别
QPS:设定QPS后,如果1s内访问量操作所设定的值,用户还没有进入到线程处理中就被挡在大门外了
线程数:设置单机阈值后,访问只能由一个线程处理,如果A接口中的线程没有处理完当前业务,又有用户访问A接口,则会报错
控制层代码
@RestController
public class FlowLimitController {
@GetMapping("/testA")
public String testA() throws InterruptedException {
System.out.println(Thread.currentThread().getName());
// 暂停多少s
TimeUnit.SECONDS.sleep(2);
return Thread.currentThread().getName() + "\t------------testA";
}
@GetMapping("/testB")
public String testB() {
return "------------testB";
}
}
测试
线程数,单机阈值:指的是服务器运行开多少个线程访问controller层
访问:http://localhost:8401/testA,在2s内再访问 http://localhost:8401/testA,就会直接报错
这里有一个问题:当你使用浏览器打开两个页面访问同一个url的时候,出现如下情况,你会先,当在2s内访问第二次的时候一直在转圈,而不是直接给予拒绝响应
关于微软Edge浏览器同一个url访问问题
当你使用浏览器打开两个页面访问同一个url的时候,浏览器是这样做的
- 首先第一次访问url
- 这时候还没等到第一次访问返回结果,我就开始新打开一个标签进行第二次访问同一个url
- 第2次访问的url会等第一次访问返回结果后才会向服务器发送第二次请求
那我们该如何处理这种情况呢?想要第二次访问不要等到第一次访问返回结果才去进行访问服务器
很简单,只要你在第二次访问的页面上按F12,打开控制台即可
关于谷歌浏览器同一个url访问问题
不知道解决办法
关于火狐浏览器同一个url访问问题
火狐浏览器没有出现上述情况,可以正常使用,推荐以后开发中使用火狐浏览器
使用火狐浏览器接着测试
关联
是什么
当关联的资源达到阈值时,就限流自己
当与A关联的资源B达到阈值后,就限流自己
B惹事,A挂了
配置A
当关联资源/testB的qps阈值超过1时,就限流/testA的Rest访问地址,当关联资源到阈偵后限制配置好的资源名
postman模拟并发密集访问testB
访问testB成功
postman里新建多线程集合组
先保存url
创建线程集合组
大批量线程高并发访问B,导致A失效了
这时候使用浏览器访问A,A访问失败
默认的流控处理
直接失败,抛出异常
Blocked by Sentinel (flow limiting)
源码
com.alibaba.csp.sentinel.slots.block.flow.controller.DefaultController
预热
说明
公式:阈值除以coldFactor(默认值为3),经过预热时长后才会达到阈值
官网
源码
com.alibaba.csp.sentinel.slots.block.flow.controller.WarmUpController
Warmup配置
默认 coldFactor为3,即请求QPS从( threshold/3)开始,经多少预热时长才逐渐升至设定的QPS阈值。
案例,阀值为10+预热时长设置5秒 系统初始化的阀值为10/3约等于3即阀值刚开始为3;然后过了5秒后阀值才慢慢升高恢复到10
测试
多次点击http://localhost:8401/testB
刚开始会出现访问错误,过了5s后才不会发生错误
应用场景
如:秒杀系统在开启的瞬间,会有很多流量上来,很有可能把系统打死,预热方式就是把为了保护系统,可慢慢的把流量放进来,慢慢的把值增长到设置的阈值
排队等待
匀速排队,阈值必须设置为QPS
官网
这种方式主要用于处理间隔性突发的流量,例如消息队列。想象一下这样的场景,在某一秒有大量的请求到来,而接来的几秒则处于空闲状态,我们希望系统能够在接下来的空闲期间逐渐处理这些请求,。而不是在第1s直接拒绝多余的请求
源码
com.alibaba.csp.sentinel.slots.block.flow.controller.RateLimiterController
配置
测试
查看控制台打印,你会发现1s打印一次,也就是说1s内只允许一个请求过来,其余请求请等待