Alibaba Spring Cloud 十六 Sentinel 流量控制
概述
在分布式或微服务场景下,系统通常需要应对不可预测的流量高峰或突发流量冲击。为了避免由于某个服务被流量“打爆”而引发连锁故障,常见做法就是对服务接口进行限流。Spring Cloud Alibaba Sentinel 提供了非常灵活且强大的流量控制(Rate Limiting)能力,帮助我们在不同场景下保护服务的稳定性。
流量控制的核心概念
-
资源(Resource)
- 资源是 Sentinel 进行限流保护的最小粒度,可以是一个方法、一个服务接口,甚至是一个代码块。
- 在 Spring Cloud Alibaba 中,常见做法是借助
@SentinelResource
注解标记接口或者在网关层对路径/服务进行保护。
-
规则(Rule)
- 流量控制规则决定了对某个资源施加怎样的限流策略和阈值。
- 常见要素:
- 限流阈值类型:QPS 或并发线程数(
grade
) - 阈值大小(
count
) - 流控效果(
controlBehavior
,例如快速失败、冷启动(Warm Up)、排队等待) - 流控模式(
strategy
,可以基于调用关系做链路限流,也可以做默认的直接限流等)
- 限流阈值类型:QPS 或并发线程数(
-
控制效果(Control Behavior)
Sentinel 提供多种限流行为:- 快速失败(RuleConstant.CONTROL_BEHAVIOR_DEFAULT):超过阈值后,直接拒绝请求并抛出异常。
- 预热/冷启动(RuleConstant.CONTROL_BEHAVIOR_WARM_UP):通过预热方式逐步提升限流阈值,一般适合突发流量时保护系统缓慢升压,避免系统瞬时过载。
- 排队等待(RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER):超出阈值时排队,超过超时时间后直接拒绝。
-
调用关系策略(Strategy)
- 可以根据调用链路来配置限流规则,当某个上游->下游的调用链路达到阈值时才进行限流,而不是对所有调用统一限流。
- 对于资源间有复杂调用链路的情况,能实现更精准的限流效果。
流量控制的常见配置方式
1. 通过控制台配置
Sentinel 提供了可视化的控制台(Dashboard),能够实时监控应用的 QPS、RT(响应时间)、限流熔断触发次数等,同时也可以动态管理流控规则,主要流程如下:
-
启动 Sentinel 控制台
- 下载或打包 Sentinel Dashboard 工程(典型端口为 8080),启动后访问
http://localhost:8080
。
- 下载或打包 Sentinel Dashboard 工程(典型端口为 8080),启动后访问
-
应用集成 Sentinel
- 在
pom.xml
中引入依赖:<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> <version>2.2.10.RELEASE</version> </dependency>
- 在
application.yml
中配置应用与控制台之间的通信端口和控制台地址:spring: cloud: sentinel: transport: port: 8719 dashboard: 127.0.0.1:8080
- 在
-
在代码中标记资源(可选)
- 可以使用
@SentinelResource
注解将接口或方法注册为受保护的资源:@RestController public class DemoController { @GetMapping("/hello") @SentinelResource("helloResource") public String hello() { return "Hello Sentinel!"; } }
- 如果未使用注解,Sentinel 也可通过
SphU.entry("someResource")
手动埋点。
- 可以使用
-
在 Sentinel 控制台配置流控规则
- 在“流控规则”页面添加一条规则:
- 资源名:
helloResource
- 限流阈值类型:QPS
- 阈值:如
5
- 流控行为:快速失败、排队等待或预热
- 资源名:
- 保存后,这条规则会动态下发到应用,实时生效。
- 在“流控规则”页面添加一条规则:
2. 通过配置文件/代码硬编码规则
除了在控制台动态配置,也可以在项目启动时,通过配置文件或代码直接加载规则。例如通过 Spring Boot 项目中的自定义配置类:
@Configuration
public class SentinelConfig implements InitializingBean {
@Override
public void afterPropertiesSet() throws Exception {
initFlowRules();
}
private void initFlowRules() {
List<FlowRule> rules = new ArrayList<>();
FlowRule rule = new FlowRule();
rule.setResource("helloResource");
// 基于 QPS 的阈值类型
rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
// 每秒最多只能通过 5 个请求
rule.setCount(5);
// 超过阈值后直接拒绝
rule.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_DEFAULT);
rules.add(rule);
FlowRuleManager.loadRules(rules);
}
}
这种方式在应用启动时就会将流控规则加载到本地,但后续动态调整需要重新部署或结合其他配置中心的监听机制(如 Nacos、Apollo 等)。
流量控制策略详解
-
按 QPS 限流(FLOW_GRADE_QPS)
- 对某资源的每秒请求数(QPS)进行限流,一旦超过设置的阈值,触发限流动作。
-
按并发数限流(FLOW_GRADE_THREAD)
- 监控某资源当前的并发线程数,超出阈值即拒绝后续请求。
- 适用于在高并发场景下避免线程资源耗尽。
-
流控行为
- 快速失败:最简单的限流方式,一旦超出,立即抛
FlowException
。 - 预热(Warm Up):一般用于系统对流量敏感、需要逐步提升负载能力的场景,比如 JVM 大量类加载或数据库连接池预热等。预热会先以较低限流阈值开始,经过
coldFactor
(默认 3)倍时间后,再提升到设定的最大阈值。 - 排队等待:超出的请求会进入队列等待,如果在设定的超时时间内仍未得到处理,则抛出限流异常。
- 快速失败:最简单的限流方式,一旦超出,立即抛
-
流控模式
- 直接模式:对指定资源本身进行限流。
- 关联模式:当关联的某个资源达到阈值时,对当前资源进行限流。
- 链路模式:基于调用链路来判断是否限流,可用于只在某些调用来源触发时进行限流。
流控异常的处理
Sentinel 对超出限流阈值的请求会抛出一个特定异常(FlowException
)。在 Spring Cloud Alibaba 场景中,可以通过以下方式来处理这种异常:
@SentinelResource
注解中的blockHandler
- 当资源被限流或降级时,调用
blockHandler
指定的方法:@SentinelResource(value = "helloResource", blockHandler = "handleHelloBlock") public String hello() { return "Hello Sentinel!"; } public String handleHelloBlock(BlockException ex) { return "Oops, blocked by Sentinel: " + ex.getClass().getSimpleName(); }
- 当资源被限流或降级时,调用
- 全局异常处理
- 通过 Spring MVC 的全局异常处理(如
@ControllerAdvice
)捕获FlowException
,返回自定义提示或降级结果。
- 通过 Spring MVC 的全局异常处理(如
与其他功能的结合
-
与熔断降级结合
- 通过在高压力或高错误率场景下同时配置熔断降级规则,进一步保证在访问量激增时系统能够快速保护并恢复。
-
与热点参数限流结合
- 如果同一个接口里存在不同参数,且某些参数出现特别高的访问频次(热点),Sentinel 提供热点参数限流功能,可以为不同的参数单独设置 QPS 阈值。
-
与系统保护规则结合
- 当整体系统资源(CPU/Load/Memory)处于高水位时,自动进行限流,防止系统过载。
常见场景示例
-
电商秒杀/大促场景
- 热点商品下单接口的 QPS 高度集中,可以使用热点参数限流或链路限流,避免单一接口将服务“打爆”。
-
限流 + 缓存
- 缓存服务在高并发下容易出现热点 key,配合 Sentinel 的限流策略可有效保护缓存后端。
-
网关层限流
- 如果使用 Spring Cloud Gateway 或 Nginx Ingress,结合 Sentinel 可以在网关层面实现全局或基于路径的流控策略。
总结
Spring Cloud Alibaba Sentinel 在流量控制方面具有以下优势:
- 多维度限流:支持基于 QPS、线程数、热点参数、调用链路等多维度配置限流规则。
- 多种控制策略:提供“快速失败”、“排队等待”、“预热”等多种限流行为,可根据业务场景灵活选择。
- 可视化配置:Sentinel 控制台能实时监控和动态调整流控规则,无需重新部署应用。
- 与 Spring Cloud 生态深度整合:通过
@SentinelResource
或自动化配置,集成成本低。
借助 Sentinel 的流量控制能力,可以让我们在微服务架构下更从容地应对高并发和流量洪峰,为系统的稳定运行保驾护航。