Sentinel 三种流控模式
Posted 流楚丶格念
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Sentinel 三种流控模式相关的知识,希望对你有一定的参考价值。
文章目录
流控模式
在添加限流规则时,点击高级选项,可以选择三种流控模式:
流控模式 | 说明 |
---|---|
直接 | 统计当前资源的请求,触发阈值时对当前资源直接限流,也是默认的模式 |
关联 | 统计与当前资源相关的另一个资源,触发阈值时,对当前资源限流 |
链路 | 统计从指定链路访问到本资源的请求,触发阈值时,对指定链路限流 |
例如下图我们在Sentinel控制台中查看簇点链路,选择任一请求的流控,选择高级选项,就能看到是那种流控模式:
1.直接模式
可以参考快速入门测试的案例,这就是直接模式:https://yangyongli.blog.csdn.net/article/details/125948236
2.关联模式
关联模式:统计与当前资源相关的另一个资源,触发阈值时,对当前资源限流
配置规则:
语法说明:当/write资源访问量触发阈值时,就会对/read资源限流,避免影响/write资源。
使用场景:比如用户支付时需要修改订单状态,同时用户要查询订单。查询和修改操作会争抢数据库锁,产生竞争。业务需求是优先支付和更新订单的业务,因此当修改订单业务触发阈值时,需要对查询订单业务限流。
需求说明:
-
在OrderController新建两个端点:/order/query和/order/update,无需实现业务
-
配置流控规则,当/order/ update资源被访问的QPS超过5时,对/order/query请求限流
1)定义/order/query端点,模拟订单查询
@GetMapping("/query")
public String queryOrder()
return "查询订单成功";
2)定义/order/update端点,模拟订单更新
@GetMapping("/update")
public String updateOrder()
return "更新订单成功";
重启服务,访问两个请求
查看sentinel控制台的簇点链路:
3)配置流控规则
对哪个端点限流,就点击哪个端点后面的按钮。我们是对订单查询/order/query限流,因此点击它后面的按钮:
在表单中填写流控规则:
流控规则中多出了一个规则则成功:
4)在Jmeter测试
测试流控模式-关联:
可以看到1000个用户,100秒,因此QPS为10,超过了我们设定的阈值:5
查看http请求:
请求的目标是/order/update,这样这个断点就会触发阈值。
但限流的目标是/order/query,我们在浏览器访问,可以发现被限流了:
当更新订单请求结束时,我们再访问查询请求,成功了
5)总结
当满足下面条件时可以使用关联模式:
- 两个有竞争关系的资源,例如上述中的查询与更新,要优先让更新操作执行
- 一个优先级较高,一个优先级较低。
3.链路模式
链路模式:只针对从指定链路访问到本资源的请求做统计,判断是否超过阈值。
配置示例:
例如有两条请求链路:
-
/test1 --> /common
-
/test2 --> /common
如果只希望统计从/test2进入到/common的请求,则可以这样配置:
实战案例
需求:有查询订单和创建订单业务,两者都需要查询商品。针对从查询订单进入到查询商品的请求统计,并设置限流。
步骤:
-
在OrderService中添加一个queryGoods方法,不用实现业务
-
在OrderController中,改造/order/query端点,调用OrderService中的queryGoods方法
-
在OrderController中添加一个/order/save的端点,调用OrderService的queryGoods方法
-
给queryGoods设置限流规则,从/order/query进入queryGoods的方法限制QPS必须小于2
实现:
1)添加查询商品方法
在order-service服务中,给OrderService类添加一个queryGoods方法:
public void queryGoods()
System.err.println("查询商品");
2)查询订单时,查询商品
在order-service的OrderController中,修改/order/query端点的业务逻辑:
@GetMapping("/query")
public String queryOrder()
// 查询商品
orderService.queryGoods();
// 查询订单
System.out.println("查询订单");
return "查询订单成功";
3)新增订单,查询商品
在order-service的OrderController中,修改/order/save端点,模拟新增订单:
@GetMapping("/save")
public String saveOrder()
// 查询商品
orderService.queryGoods();
// 查询订单
System.err.println("新增订单");
return "新增订单成功";
4)给查询商品添加资源标记
默认情况下,OrderService中的方法是不被Sentinel监控的,需要我们自己通过注解来标记要监控的方法。
给OrderService的queryGoods方法添加@SentinelResource注解:
@SentinelResource("goods")
public void queryGoods()
System.err.println("查询商品");
链路模式中,是对不同来源的两个链路做监控。但是sentinel默认会给进入SpringMVC的所有请求设置同一个root资源,会导致链路模式失效。
我们需要关闭这种对SpringMVC的资源聚合,修改order-service服务的application.yml文件:
spring:
cloud:
sentinel:
web-context-unify: false # 关闭context整合
重启服务,访问/order/query和/order/save,可以查看到sentinel的簇点链路规则中,出现了新的资源:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-unj0KVdU-1658562805502)(C:/Users/Yang/AppData/Roaming/Typora/typora-user-images/image-20220723154631294.png)]
5)添加流控规则
点击goods资源后面的流控按钮,在弹出的表单中填写下面信息:
只统计从/order/query进入/goods的资源,QPS阈值为2,超出则被限流。
6)Jmeter测试
可以看到这里200个用户,50秒内发完,QPS(每秒查询率 )为4,超过了我们设定的阈值2
一个http请求是访问/order/save:
运行的结果,完全不受影响:
另一个是访问/order/query:
运行结果,每次只有2个通过:
总结
流控模式有哪些?
流控模式 | 说明 |
---|---|
直接 | 统计当前资源的请求,触发阈值时对当前资源直接限流,也是默认的模式 |
关联 | 统计与当前资源相关的另一个资源,触发阈值时,对当前资源限流 |
链路 | 统计从指定链路访问到本资源的请求,触发阈值时,对指定链路限流 |
以上是关于Sentinel 三种流控模式的主要内容,如果未能解决你的问题,请参考以下文章