如何使用sentinel进行流量控制
前置条件
依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
配置yml
server:
port: 10001
spring:
application:
name: cloud-consumer-feign
cloud:
nacos:
discovery:
namespace: public
server-addr: localhost:8848
//[0]
sentinel:
transport:
dashboard: localhost:8080
port: 8719
- [0]处 为配置sentinel,dashboard时sentinel后台管理页面地址,port为sentinel api 端口
实践—限流配置
- 新建一个测试接口
@GetMapping("/testA")
public String testA() {
return "test A port:" + port;
}
- 进入dashboard
浏览器输入上述配置的dashboard地址用户名密码都是 sentinel
先看侧边栏,第一道划线处为当前配置sentinel的服务,看上面 “配置yml” 处配置的spring.apploication.name=cloud-consumer-openfeign就知道为什么这里名字时cloud-consumer-openfeign了。
- 点开簇点链路
可以看到这已经有一些请求过来了,还可以看到我们之前测试openfeign时调用的 /consumerHello接口实际时调用了cloud-provider-payment的 hello接口
-
请求测试接口
-
回到后台页面刷新
可以看到testA接口已经被探测到了,由此可见sentinel他是懒加载的。即只有接口请求之后才会被sentinel发现。
下面我们围绕流控,熔断,降级,热点,授权分别举例子来说明
流控
-
如何添加流控规则
- 在簇点链路界面选择点击接口的流控的按钮
-
点击新增或者新增并继续添加,并配置规则(稍后说)
-
切换到流控规则页面,此时就会多一条流控的规则的信息
-
参数说明
-
回到我们新建流控规则的簇点链路界面。再次点击 “流控” 按钮,我们来看看参数时是什么意思
资源名:接口名
针对来源:Sentinel可以针对调用者进行限流,填写微服务名,指定对哪个微服务进行限流 ,默认default(不区分来源,全部限制)
阈值类型:
- QPS: 每秒钟的请求数量,当调用该接口的QPS达到了阈值的时候,进行限流;
- 并发线程数:当调用该接口的线程数达到阈值时,进行限流
单机阈值:限流的阈值
流控模式:
- 直接:接口达到限流条件时,直接限流
- 关联:当关联的资源达到阈值时,就限流自己
- 链路:只记录指定链路上的流量(指定资源从入口资源进来的流量,如果达到阈值,就可以限流)[api级别的针对来源]
流控效果:
- 快速失败:直接失败
- Warm Up:即请求 QPS 从 threshold / 3 开始,经预热时长逐渐升至设定的 QPS 阈值。点击后可以选择预热时长
- 排队等待:排队等待点击之后可以设置等待时间
-
-
如何编辑规则
如图直接填写参数就好。
-
QPS模式->直接->直接失败演示
我们配置限流为 每秒只能请求一次 /testA接口,现在测试。如下图可以看到,当我们请求过快之后,第二次就失败了
并且失败之后会有如下字样,这是sentinel自带的失败处理,我们后面可以自定义。
选择直接失败就会直接返回如上字样,告知你接口被限流了。
-
QPS模式->直接->warm up演示
该方式主要用于系统长期处于低水位的情况下,当流量突然增加时,直接把系统拉升到高水位可能瞬间把系统压垮。通过"冷启动",让通过的流量缓慢增加,在一定时间内逐渐增加到阈值上限,给冷系统一个预热的时间,避免冷系统被压垮的情况。
- 假设我们设置如下
阈值:3,预热时长 :6。会限制QPS到3/3次,然后经过6秒之后 加到QPS为3。
-
jmeter配置
每秒三个请求
-
测试结果
可以发现很明显的刚开始三个只能成功一个,后面三个就全部成功了。
-
QPS模式->直接->排队等待演示
-
流控规则配置如下
-
jmeter配置
一秒发五个请求
-
测试结果
-
分析一下为什么有一个会失败,因为QPS为3,所以有三个肯定成功,触发排队等待之后。每三分之一秒会处理一个数据。而我们的超时时间为500ms。
所以最后被后端接受处理的两个请求必定有一个要等待600ms才会被处理。所以就会失败。
注意:图中的顺序并不是,后端处理的顺序。理论上他们是同一时间到达后端的。
-
QPS模式->关联->快速失败演示
这里我只演示一个剩下的大家举一反三即可
-
新建关联接口 /testB
@GetMapping("/testB") public String testB() { return "test B port:" + port; }
-
流控规则配置如下
- /testA
- /testB
-
jemter配置
请求 /testB 一秒两次触发限流
-
结果
可以看见 /testA被限流了,当我们取消调/testA的测试 立马 /testA接口就又好了。
-
-
QPS模式->链路->快速失败演示
同样这个模式,我也只演示一个。其他的依然可以举一反三或者通过查文档解决.
-
流控配置
这次调用链路为 chain1->chain2->chain3
此处入口资源填写来自于簇点链路页面
因为chain1被我整合在了gateway服务里面,所以这里看不到。但我们同样可以用这个举例子。
a->b->d, a->b->e, a->c->f, a->c->g均可视作链路。 假设我以a为入口资源,d为终点资源,对这条链路进行限制的话,则资源a,b,d均会被限制访问。
同样如果我们对chain2进行了链路流控,则从入口资源到chain2的位置的资源就会被限流。
-
测试
请求过快会导致限流
再来看看chain3则完全不受影响
所以链路流控更加像是区间流控,它会限流一个区间。
-
-
流控总结
- 通过页面配置可以完成大部分流控
- 限流措施又三种直接失败,warm up,排队等待
- 限流阈值类型有两种:QPS和并发线程数
- 限流对象有三种:直接(单点) ,关联,链路(区间)