Spring Cloud Alibaba 之 Sentinel 集成限流
Spring Cloud Alibaba 之 Sentinel 集成限流
一、什么是 Sentinel?
Sentinel 是面向分布式服务架构的流量控制组件,主要以流量为切入点,从流量控制、熔断降级、系统自适应保护等多个维度来帮助您保障微服务的稳定性。
二、Sentinel 入门
Sentinel 不算是个复杂的东西,集成起来很容易,但是我们需要理解其中的一些概念性东西。
- 资源: 资源并不是一个很难理解的东西, 正如它的名字在可以理解为在 Sentinel 中,需要被 Sentinel 所管理不管是需要被限流还是熔断的接口都是资源。
- 规则: 规则即围绕不同的资源来制定不同的控制策略,在开发过程中,我们通过对不同的资源进行分类,从而达到因地制宜的效果。
三、官方文档
四、限流参数与规则
1. 限流参数
| Field | 说明 | 默认值 |
|---|---|---|
| resource | 资源名,资源名是限流规则的作用对象 | |
| count | 限流阈值 | |
| grade | 限流阈值类型,QPS 或线程数模式 | QPS 模式 |
| limitApp | 流控针对的调用来源 | default,代表不区分调用来源 |
| strategy | 调用关系限流策略:直接、链路、关联 | 根据资源本身(直接) |
| controlBehavior | 流控效果(直接拒绝 / 排队等待 / 慢启动模式),不支持按调用关系限流 | 直接拒绝 |
2. 限流规则
- 拒绝策略: 顾名思义,超出限流的限制就直接抛异常
- 冷启动策略: 通过"冷启动",让通过的流量缓慢增加,在一定时间内逐渐增加到阈值上限,给冷系统一个预热的时间,避免冷系统被压垮的情况。PS:用了下发现同样的超出阈值限制会抛异常,相信绝大部分系统都是应该尽量满足请求通过完成的,哪怕因为峰值要多等会儿,而不是抛异常,所以我选择下面那个策略。
- 匀速启动策略配置: 这个策略可以让你的请求在 1S 内平均的匀速运行。举个栗子,假如定义 QPS=2,那么这个策略会将 1S 平均分为 2 个 500ms,每个 500ms 去运行一个请求。PS:注意配置队列中请求的等待时间,假如设置等待时间最长为 20s,那么你的请求最多可以在队列中等待 20s,期间一有空闲就可以顺序被执行而不是抛异常。默认值只有 500ms,所以一下就超时了,超时的时候就会抛异常。个人觉得这个是最符合绝大多数场景的策略。
三、集成
1. 引入依赖
<!--sentinel-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
<version>2.2.7.RELEASE</version>
</dependency>
2. 配置资源以及规则策略
/**
* @author Jinpeng Lin
* @description Sentinel 配置
* @date 2022-03-21
*/
@Configuration
public class SentinelConfig {
/**
* 资源名
*/
public static final String MY_RESOURCE = "my-resource"
@Bean
public SentinelResourceAspect sentinelResourceAspect() {
return new SentinelResourceAspect();
}
@PostConstruct
public void sentinelConfig() {
// 1.注册 熔断降级规则
List<FlowRule> rules = Lists.newArrayList();
rules.add(this.initFlowRules());
// 限流管理器
FlowRuleManager.loadRules(rules);
}
/**
* 初始化倍罗限流规则
* @return
*/
private FlowRule initFlowRules() {
FlowRule rule = new FlowRule();
rule.setResource(SentinelConfig.MY_RESOURCE);
// QPS 策略限制:RuleConstant.FLOW_GRADE_QPS
// 线程策略限制:RuleConstant.FLOW_GRADE_THREAD
rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
// 设置 QPS 数量
rule.setCount(3);
// 拒绝策略:RuleConstant.CONTROL_BEHAVIOR_DEFAULT
// 冷启动策略:RuleConstant.CONTROL_BEHAVIOR_WARM_UP
// 匀速启动策略:RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER
rule.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER);
// 匀速启动策略配置:设置队列中请求的最大等待时长,默认只有 500毫秒,超出等待时长的失败
rule.setMaxQueueingTimeMs(20 * 1000);
// 冷启动策略配置:warmUpPeriodSec 代表期待系统进入稳定状态的时间(即预热时长)
// rule.setWarmUpPeriodSec(10);
}
}
3. 配置超时降级策略
- 降级策略参数为被拦截接口参数的参数基础上,加一个异常参数
- 降级的代码的返回值与被拦截接口返回值相同
/**
* @author Jinpeng Lin
* @description Sentinel 异常处理
* @date 2022-03-22
*/
@Slf4j
public class SentinelExceptionHandler {
/**
* 限流降级
* 限流规则:限流参数必须在被限流的接口上多个接收异常的参数,返回值必须与原接口相同
* @param name
* @param ex
* @return
*/
public static String exceptionHandler(String name, BlockException ex) {
System.out.println(ex);
return "请求失败了";
}
}
4. 策略应用
@SentinelResource(value = SentinelConfig.MY_RESOURCE, blockHandler = "exceptionHandler",
blockHandlerClass = {SentinelExceptionHandler.class})
@GetMapping("/test/{name}")
public String test(@PathVariable("name") String name) {
return "请求成功:" + name;
}