在上一篇文章中,我们已经对 Sentinel
有了基本的了解,并通过一个基本案例看到了 Sentinel
的流控效果,今天我们就来研究一下 Sentinel
的流控规则。
话不多说,开始今天的学习。
一、什么是流控
流控:即流量控制,通常所说的缓冲、限流、降级、熔断等在本质上是一致的,均为流量控制手段,用于防止系统过载,区别在于流控的手段和程度不同。
那么为什么要进行流控呢?
因为大型互联网应用都会有大量的用户流量,当遇到了某些特殊的时间节点,如:双十一秒杀、春节抢票等,大量的流量突然涌入系统,容易引发系统过载,造成系统整体的不稳定甚至崩溃。
那么对这种问题,我们就需要对流量进行限制,对于超过限制的流量,我们可以采用熔断、降级、排队等待等方式来解决。
二、基本流控规则
在上一篇 微服务系列:Spring Cloud Alibaba 之 Sentinel 详细入门 Sentinel
入门篇中,我们启动了 Sentinel
控制台,并在项目中集成了 Sentinel
这次我们依旧启动控制台,并写一个这样的测试接口:
@RestController
public class TestController {
@GetMapping("/testA")
public String testA(){
return "testA....";
}
@GetMapping("/testB")
public Object testB(){
return "testB......";
}
}
浏览器访问地址:localhost:9201/testA,观察控制台簇点链路菜单
出现了我们刚才访问的那个接口资源
1. 控制台定义
点击 “流控” 按钮,添加 /testA
接口的流量控制的规则
其中:
- 资源名: 唯一名称,默认请求路径
- 针对来源: Sentinel可以针对调用者进行限流,填写微服务名,默认default(不区分来源)官方文档 - 根据调用方限流
- 阈值类型/单机阈值:
- QPS(每秒请求数量):当调用该api的QPS达到阈值的时候,进行限流
- 线程数:当调用该api的线程数达到阈值的时候,进行限流
- 是否集群: 不需要集群
这些参数就是配置 Sentinel
的基本流控规则的参数,至于高级选项中的配置,我们本篇暂不学习,将在下一篇中去学习 Sentinel
的高级流控规则
2. 代码定义
理解上面规则的定义之后,我们可以通过调用FlowRuleManager.loadRules()
方法来用硬编码的方式定义流量控制规则,比如:
private void initFlowQpsRule() {
List<FlowRule> rules = new ArrayList<>();
FlowRule rule = new FlowRule(resourceName);
rule.setCount(2);
rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
rule.setLimitApp("default");
rules.add(rule);
FlowRuleManager.loadRules(rules);
}
属性说明:
参数 | 描述 | 描述 |
---|---|---|
resourceName | 资源名,资源名是限流规则的作用对象 | |
limitApp | 流控针对的调用来源,若为 default 则不区分调用来源 | default,代表不区分调用来源 |
grade | 限流阈值类型,QPS 模式(1)或并发线程数模式(0) | QPS 模式 |
count | 限流阈值 | |
strategy | 调用关系限流策略:直接、链路、关联 | 根据资源本身(直接) |
controlBehavior | 流量控制效果(直接拒绝、Warm Up、匀速排队) | 直接拒绝 |
clusterMode | 是否集群限流 | 否 |
前四个参数就与上面控制台中的基本规则相对应,下面的三个参数就对应高级规则啦,依旧是本篇暂不讨论。
限流的直接表现是在执行 Entry nodeA = SphU.entry(资源名字)
的时候抛出 FlowException
异常。FlowException
是 BlockException
的子类,你可以捕捉 BlockException
来自定义被限流之后的处理逻辑。
注意:
同一个资源可以同时有多个限流规则,会对该资源的所有限流规则依次遍历,直到有规则触发限流或者所有规则遍历完毕。
三、流控测试
经过上面的学习,相信你对 Sentinel
的基本限流规则配置有了一定了解,接下来我们就来实战操作一下。
1. 控制台定义
1.1、QPS
QPS(每秒请求数量):当调用该api的QPS达到阈值的时候,进行限流
我们设置资源 /testA
的阈值类型是 QPS,单机阈值是 2
点击新增就会发现流控规则菜单下多了一条新规则
这条规则的意思就是:当每秒访问资源 /testA
的请求超过 2 个时,触发限流
然后我们快速刷新请求:localhost:9201/testA 当一秒内刷新了 2 次,到第 3 次的时候将触发限流
怎么样?是不是觉得 Sentinel
控制台配置限流规则非常的方便,并且不用重启项目和控制台,即刻生效。
1.2、并发线程
当调用该api的线程数达到阈值的时候,进行限流
线程数限流用于保护业务线程数不被耗尽,如果超出阈值,新的请求会被立即拒绝。
我们设置资源 /testA
的阈值类型是 QPS,单机阈值是 3
这条规则的意思就是:当同时访问资源 /testA
的线程数超过 3 个时,触发限流,第四个请求会被立即拒绝
了解了一下,
Postman
的 runner 并不是并发执行的,实际还是串行
所以,这里并发测试工具我们选择使用 Jemeter
Jemter
的下载安装这里就不介绍了,我们直接开始
a. 添加线程组
b. 设置线程数为5和永远循环
c. 添加取样器
配置访问的接口信息
d. 添加个监听器,看访问结果
e. 点击启动测试
f. 结果
启动过程中,浏览器访问这个地址很容易就出现了限流
2. 代码定义
接下来我们使用代码硬编码的方式来定义流量控制规则
initFlowQpsRule()
@SpringBootApplication
public class SentinelApplication {
public static void main(String[] args) {
SpringApplication.run(SentinelApplication.class, args);
initFlowQpsRule();
}
//定义了每秒最多接收3个请求
private static void initFlowQpsRule() {
List<FlowRule> rules = new ArrayList<>();
FlowRule rule = new FlowRule("testA");
rule.setCount(3);
rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
rule.setLimitApp("default");
rules.add(rule);
FlowRuleManager.loadRules(rules);
}
}
- TestController.java
@RestController
public class TestController {
@GetMapping("/testA")
@SentinelResource(value = "testA", blockHandler = "handleException")
public String testA(){
return "testA....";
}
public String handleException(BlockException exception){
return "{\"code\":\"500\",\"msg\": \"" + "服务流量控制处理\"}";
}
}
注意:handleException 方法中参数必须和
testA
参数一致并且最后要加上参数BlockException exception
,否则会报错
- 重启项目,并访问地址
访问地址:localhost:9201/testA
流控规则下也自动出现了这条规则
- 快速刷新地址
快速刷新地址:localhost:9201/testA 触发限流
到这里,Sentinel
的基本流控规则我们就会配置啦,下一篇我们就去研究 Sentinel
的高级流控规则
PS: 都看到这里了,点个赞吧,彦祖!