Sentinel 流量控制与熔断降级
一、为什么我们需要 Sentinel?
1. 微服务架构的致命威胁:服务雪崩
在微服务架构中,一个请求往往需要调用多个服务才能完成。如果其中一个服务出现故障,响应变慢,那么上游服务的线程就会被阻塞在这个慢调用上。
随着越来越多的请求被阻塞,上游服务的线程池会被占满,无法处理新的请求,最终导致上游服务也不可用。这个故障会像多米诺骨牌一样逐级传递,最终导致整个系统崩溃,这就是服务雪崩效应。
2. 传统解决方案的局限性
为了解决服务雪崩问题,人们提出了很多解决方案:
- 超时机制:给每个请求设置超时时间,避免线程无限等待
- 舱壁模式:每个服务使用独立的线程池,避免一个服务拖垮整个应用
- 熔断模式:当服务故障率达到阈值时,直接熔断该服务,快速失败
Hystrix 是最早的熔断框架,但它已经停止开发,而且存在很多缺点:
- 配置复杂,学习成本高
- 依赖 Netflix 生态,和 Spring Cloud Alibaba 整合不好
- 不支持流量控制、热点参数限流等功能
- 没有可视化控制台,运维困难
3. Sentinel 的核心价值
Sentinel 是阿里巴巴开源的轻量级流量控制框架,它以流量为切入点,从流量控制、熔断降级、系统自适应保护等多个维度来保护服务的稳定性。
Sentinel 的核心优势:
- 轻量级:核心包只有几百 KB,引入后几乎没有性能损耗
- 功能丰富:支持流量控制、熔断降级、热点参数限流、系统保护、黑白名单等
- 简单易用:提供可视化控制台,一键配置规则,实时监控
- 生态完善:无缝整合 Spring Cloud Alibaba、Dubbo、gRPC 等主流框架
- 高可用:支持集群限流、规则持久化,满足生产环境需求
二、Sentinel 核心概念
要真正用好 Sentinel,必须先搞懂它的核心概念。
1. 资源(Resource)
资源是 Sentinel 的核心概念,它可以是任何东西:一个接口、一段代码、一个数据库查询、一个 RPC 调用。
所有需要被保护的东西都可以定义为资源,Sentinel 会对资源进行流量控制和熔断降级。
2. 规则(Rule)
规则是 Sentinel 用来判断是否需要对资源进行保护的依据。Sentinel 支持多种类型的规则:
- 流量控制规则:限制资源的 QPS
- 熔断降级规则:当资源故障率达到阈值时,熔断该资源
- 热点参数限流规则:针对热点参数进行限流
- 系统保护规则:从系统整体维度进行保护
- 授权规则:控制资源的访问权限
3. 流量控制(Flow Control)
流量控制的原理是监控应用流量的 QPS 或并发线程数,当达到指定的阈值时,对流量进行控制,避免系统被突发流量打垮。
Sentinel 支持多种流量控制效果:
- 直接拒绝:超过阈值的请求直接拒绝
- Warm Up:预热模式,让流量缓慢增加,避免系统突然被压垮
- 匀速排队:让请求匀速通过,适用于突发流量削峰填谷
4. 熔断降级(Circuit Breaking)
熔断降级的原理是监控资源的调用情况,当资源的慢调用比例、异常比例或异常数达到阈值时,自动熔断该资源的调用。
在熔断期间,所有对该资源的调用都会快速失败,避免故障扩散。熔断一段时间后,会进入半开状态,尝试放行部分请求,判断服务是否恢复。
5. 热点参数限流(Hot Spot Param Flow Control)
热点参数限流是针对请求中的热点参数进行限流。比如秒杀活动中,某个商品的 ID 是热点参数,我们可以针对这个商品 ID 进行单独限流,避免单个商品打垮整个系统。
三、Spring Boot 整合 Sentinel
整合 Sentinel 非常简单,只需要三步就能完成。
第一步:引入依赖
xml
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
第二步:配置 Sentinel
在application.yml中添加 Sentinel 配置:
yaml
spring:
application:
name: user-service
cloud:
sentinel:
transport:
dashboard: localhost:8080 # Sentinel 控制台地址
port: 8719 # 客户端和控制台通信端口
# 取消懒加载,启动时立即连接控制台
eager: true
第三步:启动 Sentinel 控制台
- 下载 Sentinel 控制台 jar 包:https://github.com/alibaba/Sentinel/releases
- 启动控制台:
java -jar sentinel-dashboard-1.8.6.jar - 访问http://localhost:8080,默认用户名密码都是 sentinel
现在,启动你的 Spring Boot 应用,就可以在 Sentinel 控制台看到你的服务了。
四、核心功能实战
4.1 流量控制
流量控制是 Sentinel 最基础也是最常用的功能。我们可以通过控制台为任意接口配置流量控制规则。
1. 快速入门:给接口配置 QPS 限流
- 在 Sentinel 控制台左侧菜单点击 "簇点链路"
- 找到你要限流的接口,点击 "流控" 按钮
- 配置流控规则:
- 阈值类型:QPS
- 单机阈值:10
- 流控模式:直接
- 流控效果:快速失败
现在,这个接口的 QPS 超过 10 时,超过的请求会被直接拒绝,返回Blocked by Sentinel (flow limiting)。
2. 高级流控模式
Sentinel 支持三种流控模式:
- 直接:直接限制当前资源的 QPS
- 关联:当关联资源的 QPS 达到阈值时,限制当前资源的 QPS
- 链路:只限制从指定链路进入当前资源的请求
3. 高级流控效果
Sentinel 支持三种流控效果:
- 快速失败:超过阈值直接拒绝
- Warm Up:预热模式,阈值从初始值缓慢增加到最大值,适用于系统启动时的流量控制
- 匀速排队:让请求匀速通过,适用于突发流量削峰填谷
4.2 熔断降级
熔断降级用于保护系统免受慢调用和异常的影响。Sentinel 支持三种熔断策略:
1. 慢调用比例
当资源的慢调用比例达到阈值时,熔断该资源。
- 最大 RT:慢调用的阈值,超过这个时间的调用被认为是慢调用
- 比例阈值:慢调用比例达到这个值时触发熔断
- 熔断时长:熔断持续的时间
- 最小请求数:触发熔断的最小请求数
2. 异常比例
当资源的异常比例达到阈值时,熔断该资源。
3. 异常数
当资源的异常数达到阈值时,熔断该资源。
配置示例:给/user/get接口配置熔断规则:
- 熔断策略:慢调用比例
- 最大 RT:500ms
- 比例阈值:0.5
- 熔断时长:10s
- 最小请求数:10
这个配置的意思是:当 1 秒内有至少 10 个请求,其中 50% 以上的请求响应时间超过 500ms 时,熔断该接口 10 秒。在熔断期间,所有请求都会快速失败。
4.3 热点参数限流
热点参数限流是 Sentinel 最强大的功能之一,它可以针对请求中的特定参数进行限流。
使用示例:给/user/get/{id}接口配置热点参数限流,限制每个用户 ID 的 QPS 为 5。
- 在接口上添加
@SentinelResource注解:
java
运行
@GetMapping("/get/{id}")
@SentinelResource(value = "getUserById", blockHandler = "getUserByIdBlockHandler")
public Result<User> getUserById(@PathVariable Long id) {
User user = userService.findById(id);
return Result.success(user);
}
// 限流后的处理方法
public Result<User> getUserByIdBlockHandler(Long id, BlockException e) {
return Result.fail(429, "请求过于频繁,请稍后再试");
}
- 在 Sentinel 控制台配置热点参数规则:
- 资源名:getUserById
- 参数索引:0(第一个参数)
- 单机阈值:5
- 统计窗口时长:1 秒
现在,每个用户 ID 每秒最多只能访问 5 次这个接口,超过的请求会被限流。
4.4 系统自适应保护
系统自适应保护从系统整体维度进行保护,它会监控系统的 CPU 使用率、负载、QPS、平均响应时间和并发线程数,当系统指标达到阈值时,自动限制所有入口流量,保证系统的稳定性。
在 Sentinel 控制台左侧菜单点击 "系统规则",就可以配置系统保护规则。
五、高级特性:规则持久化
默认情况下,Sentinel 的规则是存储在客户端内存中的,当客户端重启后,所有规则都会丢失。这在生产环境是完全不可行的。
Sentinel 支持多种规则持久化方式:Nacos、Apollo、ZooKeeper、MySQL 等。其中最常用的是 Nacos。
第一步:引入依赖
xml
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
第二步:配置 Nacos 数据源
在application.yml中添加 Nacos 数据源配置:
yaml
spring:
cloud:
sentinel:
datasource:
ds1:
nacos:
server-addr: localhost:8848
dataId: user-service-sentinel-flow-rules
groupId: DEFAULT_GROUP
rule-type: flow # 流量控制规则
ds2:
nacos:
server-addr: localhost:8848
dataId: user-service-sentinel-degrade-rules
groupId: DEFAULT_GROUP
rule-type: degrade # 熔断降级规则
第三步:在 Nacos 中配置规则
在 Nacos 控制台创建对应的配置文件,写入规则的 JSON 格式。比如流量控制规则:
json
[
{
"resource": "/user/get",
"limitApp": "default",
"grade": 1,
"count": 10,
"strategy": 0,
"controlBehavior": 0,
"clusterMode": false
}
]
现在,Sentinel 会自动从 Nacos 拉取规则,并且当规则发生变化时,会自动同步到客户端。
六、生产环境常见坑与最佳实践
坑 1:限流不生效
常见原因:
- 资源名写错了
- 没有添加
@SentinelResource注解 - 规则没有正确配置
- 客户端没有连接到控制台
解决方案:
- 检查资源名是否和代码中的一致
- 确保添加了
@SentinelResource注解 - 检查规则配置是否正确
- 检查客户端和控制台的网络连通性
坑 2:熔断降级不生效
常见原因:
- 异常被捕获了,没有抛出
- 熔断阈值设置不合理
- 最小请求数设置太大
解决方案:
- 确保异常能够被 Sentinel 捕获
- 根据实际业务情况合理设置熔断阈值
- 最小请求数不要设置太大,一般设置为 5-10
坑 3:热点参数限流不生效
常见原因:
- 没有添加
@SentinelResource注解 - 参数索引写错了
- 参数是基本类型的包装类,没有正确识别
解决方案:
- 必须添加
@SentinelResource注解 - 检查参数索引是否正确
- 对于包装类参数,确保参数不为 null
坑 4:规则持久化不生效
常见原因:
- 没有引入对应的数据源依赖
- Nacos 配置信息写错了
- 规则的 JSON 格式错误
解决方案:
- 确保引入了正确的数据源依赖
- 检查 Nacos 的地址、dataId、groupId 是否正确
- 验证规则的 JSON 格式是否正确
最佳实践
- 资源命名规范:使用统一的资源命名规范,比如
类名.方法名 - 合理设置阈值:根据压测结果设置合理的阈值,不要凭感觉设置
- 统一异常处理:自定义限流和熔断的异常处理,返回友好的错误信息
- 结合网关使用:在网关层统一配置流量控制规则,避免每个服务都配置一遍
- 开启监控告警:监控 Sentinel 的限流次数、熔断次数、异常数等指标,及时发现问题
- 灰度发布规则:新规则先在测试环境验证,然后灰度发布到生产环境
- 避免过度保护:不要给所有接口都加限流和熔断,只给核心接口和容易出问题的接口加
- 定期优化规则:根据系统的运行情况,定期调整规则阈值
总结
Sentinel 是微服务架构中不可或缺的流量治理组件,它就像系统的 "保险丝",能在故障发生时自动切断故障链路,保护系统不被拖垮。
- 服务雪崩是微服务架构的致命威胁,Sentinel 是解决这个问题的最佳方案
- Sentinel 的核心概念包括资源、规则、流量控制、熔断降级和热点参数限流
- Spring Boot 整合 Sentinel 非常简单,只需要引入依赖和配置
- 支持流量控制、熔断降级、热点参数限流、系统保护等多种功能
- 生产环境必须配置规则持久化,避免规则丢失
- 遵循最佳实践,避开常见的坑,让你的系统更加稳定可靠
更多推荐



所有评论(0)