Sentinel熔断限流:容错、降级、热点防护
微服务调用链就像多米诺骨牌,一个服务倒下,后面的跟着全躺。Sentinel 就是那个在关键位置挡住连锁反应的守门员。
一、雪崩效应:为什么需要熔断限流
微服务架构下,服务之间存在大量调用依赖。以无人售货柜下单流程为例:
用户 → 网关 → 订单服务 → 商品服务 → 库存服务 ↓ 支付服务 → 用户服务如果库存服务因为促销活动流量暴增导致响应变慢,会发生什么?
- 商品服务调用库存服务超时,线程阻塞等待
- 商品服务的线程池被占满,无法处理新请求
- 订单服务调用商品服务也开始超时阻塞
- 订单服务的线程池也被占满
- 最终整个调用链全部瘫痪
这就是雪崩效应——一个底层服务的故障像雪崩一样向上扩散,拖垮整个系统。
应对雪崩的三板斧:
- 限流(Flow Control):控制流量在系统可承受范围内,多余的请求直接拒绝
- 熔断(Circuit Breaking):当错误率超过阈值时,直接熔断调用,快速失败而非长时间等待
- 降级(Fallback):熔断或限流触发后,返回一个兜底结果,保证用户体验
二、Sentinel vs Hystrix:为什么选 Sentinel
| 特性 | Hystrix(已停更) | Sentinel |
|---|---|---|
| 熔断策略 | 异常比例 | 慢调用比例 + 异常比例 + 异常数 |
| 限流策略 | 信号量隔离 | QPS + 线程数 + 热点参数 |
| 控制台 | Dashboard 功能简陋 | 实时监控 + 可视化规则配置 |
| 规则配置 | 代码硬编码 | Dashboard 动态推送 + Nacos 持久化 |
| 系统自适应 | 不支持 | 支持(根据 Load/CPU 自动限流) |
| 热点参数限流 | 不支持 | 支持 |
一句话:Hystrix 只会"熔断",Sentinel 还会"限流"和"自适应",而且有可视化控制台。
三、Sentinel 核心概念
Sentinel 的设计围绕三个核心概念:
┌──────────────────────────────────┐ │ Sentinel 核心架构 │ ├──────────────────────────────────┤ │ │ │ Resource(资源) │ │ ↓ 你要保护的任何东西:一个接口、一段代码 │ │ │ │ Rule(规则) │ │ ↓ 对资源施加的限制:限流规则、熔断规则 │ │ │ │ Slot(插槽) │ │ ↓ 规则的执行链:请求经过的多个处理节点 │ │ │ └──────────────────────────────────┘- Resource(资源):可以是一个接口方法、一段代码块,甚至一个 SQL 查询。用
@SentinelResource注解标记。 - Rule(规则):对资源设置限流/熔断规则,规则可以推送到 Nacos 做持久化。
- Slot(插槽):请求进入 Sentinel 后会经过一系列 Slot(槽),每个 Slot 负责一类检查(限流检查、熔断检查、热点检查等),形成一个责任链。
四、SpringBoot 整合 Sentinel
4.1 安装 Sentinel Dashboard
Sentinel Dashboard 是独立的可视化控制台,用来配置规则和查看监控数据:
# 下载 Sentinel Dashboard 1.8.6dockerrun-d\--namesentinel-dashboard\-p8080:8080\-eSENTINEL_DASHBOARD_AUTH_USERNAME=sentinel\-eSENTINEL_DASHBOARD_AUTH_PASSWORD=sentinel\bladex/sentinel-dashboard:1.8.6访问http://localhost:8080,账号密码都是sentinel。
4.2 添加依赖
<!-- Sentinel 核心 --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId></dependency><!-- Sentinel 数据源 - Nacos(规则持久化) --><dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-datasource-nacos</artifactId></dependency>4.3 application.yml 配置
spring:cloud:sentinel:transport:dashboard:127.0.0.1:8080# Dashboard 地址port:8719# 客户端与 Dashboard 通信端口eager:true# 立即初始化(不用等第一次请求)datasource:# 规则数据源配置(Nacos 持久化)flow:nacos:server-addr:127.0.0.1:8848data-id:${spring.application.name}-flow-rules.jsongroup:SENTINEL_GROUPrule-type:flow# 规则类型:限流degrade:nacos:server-addr:127.0.0.1:8848data-id:${spring.application.name}-degrade-rules.jsongroup:SENTINEL_GROUPrule-type:degrade# 规则类型:熔断五、流控规则:QPS 和线程数
流控规则控制请求的速率,有两种阈值类型:
| 阈值类型 | 含义 | 适用场景 |
|---|---|---|
| QPS | 每秒请求数 | 限制接口的调频率 |
| 线程数 | 并发执行的线程数 | 限制同时处理的请求数 |
三种流控模式:
1. 直接(DIRECT)—— 限制资源自身的流量 请求 → 资源A(QPS限制20)→ 执行或拒绝 2. 关联(ASSOCIATE)—— 当关联资源达到阈值时,限制本资源 请求 → 资源A ──(关联)── 资源B(达到阈值) 资源A 被限制 场景:写接口流量大时限制读接口,保写不保读 3. 链路(CHAIN)—— 只限制从某个入口进来的请求 入口A → 资源C(受限) 入口B → 资源C(不受限) 场景:同一个方法被多个接口调用,只限其中一个入口流控效果:
- 快速失败:超过阈值的请求直接抛异常(默认方式)
- Warm Up(预热):刚启动时只放行少量请求,经过预热时长后逐渐达到阈值,适用于冷启动场景
- 排队等待:请求匀速通过,多余请求排队,适用于突发流量削峰
六、熔断降级规则:三种触发策略
熔断是当下游服务不健康时,主动切断调用,避免拖垮自身。Sentinel 提供三种熔断策略:
6.1 慢调用比例
当请求数 >= 最小请求数 时: 如果 慢调用比例 > 阈值比例: → 触发熔断,持续 熔断时长 → 熔断结束后进入 HALF-OPEN(半开)状态 → 放一个请求试探,成功则恢复,失败则继续熔断配置示例:
最大 RT:200ms(超过 200ms 算慢调用) 比例阈值:0.5(慢调用占比超过 50% 触发熔断) 熔断时长:10s 最小请求数:56.2 异常比例
当请求数 >= 最小请求数 时: 如果 异常比例 > 阈值比例: → 触发熔断6.3 异常数
当请求数 >= 最小请求数 时: 如果 异常次数 >= 阈值: → 触发熔断三种策略的选择逻辑:
| 策略 | 适用场景 |
|---|---|
| 慢调用比例 | 下游响应变慢时保护自身 |
| 异常比例 | 下游频繁报错时保护自身 |
| 异常数 | 下游出现严重错误时立即熔断 |
七、热点参数限流:精准打击
热点参数限流是 Sentinel 的特色功能——可以对请求参数中的特定值单独限流。
以无人售货柜为例,/product/detail接口接收productId参数。如果某个热门商品被疯狂请求,可以对这个商品 ID 单独限流,而不是限制整个接口。
@RestController@RequestMapping("/product")publicclassProductController{// value: 资源名;blockHandler: 限流后的处理方法@SentinelResource(value="getProductDetail",blockHandler="getProductDetailBlockHandler")@GetMapping("/detail")publicStringgetProductDetail(@RequestParamLongproductId){return"商品详情: "+productId;}// 热点参数限流的兜底方法,参数列表要和原方法一致,最后多一个 BlockExceptionpublicStringgetProductDetailBlockHandler(LongproductId,BlockExceptionex){return"商品 "+productId+" 太火爆了,请稍后再试";}}在 Sentinel Dashboard 中配置热点参数规则:
资源名: getProductDetail 参数索引: 0(第 0 个参数,即 productId) 单机阈值: 10 QPS 参数例外项: 参数值: 1001(爆款商品 ID) 阈值: 2 QPS(这个商品只允许 2 QPS)这样普通商品允许 10 QPS,但商品 1001 只允许 2 QPS,精准限流爆款。
八、降级处理:blockHandler vs fallback
Sentinel 的@SentinelResource提供两种降级处理方式:
| 方式 | 触发条件 | 用途 |
|---|---|---|
| blockHandler | Sentinel 规则触发(限流、熔断) | 流控降级 |
| fallback | 业务异常触发(非 Sentinel 规则的异常) | 业务降级 |
@SentinelResource(value="createOrder",blockHandler="createOrderBlockHandler",fallback="createOrderFallback")@GetMapping("/order/create")publicStringcreateOrder(@RequestParamLonguserId){// 模拟业务异常if(userId<0){thrownewRuntimeException("用户 ID 非法");}return"下单成功";}// Sentinel 规则触发时调用(限流/熔断)publicStringcreateOrderBlockHandler(LonguserId,BlockExceptionex){return"系统繁忙,请稍后再试 [限流降级]";}// 业务异常触发时调用(非 Sentinel 异常)publicStringcreateOrderFallback(LonguserId,Throwablee){return"下单失败: "+e.getMessage()+" [业务降级]";}注意区分:被 Sentinel 规则拦截走
blockHandler,业务代码抛异常走fallback。如果只想用一种,另一个留空即可。
blockHandler默认要求方法和原方法在同一个类。如果想要分开管理降级逻辑,可以用blockHandlerClass指定一个外部类,但方法必须是static的:
publicclassOrderBlockHandler{// 必须是 static 方法publicstaticStringcreateOrderBlockHandler(LonguserId,BlockExceptionex){return"系统繁忙,请稍后再试";}}@SentinelResource(value="createOrder",blockHandlerClass=OrderBlockHandler.class,blockHandler="createOrderBlockHandler")九、Sentinel Dashboard 使用
Dashboard 的核心功能:
- 实时监控:实时显示每个资源的 QPS、响应时间、异常数曲线
- 规则配置:可视化配置流控规则、熔断规则、热点规则
- 集群限流:支持集群维度的限流管理
关键提醒:Dashboard 默认的规则配置是存在内存里的,Dashboard 重启后规则丢失,应用重启后也丢失。要持久化规则,必须配合 Nacos 数据源(上面的 yaml 配置已包含)。
持久化后的规则流向:
Nacos(规则存储) ↓ 推送 应用(Sentinel 客户端) ↓ 上报监控数据 Dashboard(查看监控 + 规则下发)十、总结
Sentinel 在微服务容错体系里扮演的角色就是"保险丝 + 流量控制阀"。记住三件事:用流控规则保接口不被打爆、用熔断规则保自己不被下游拖垮、用热点参数规则实现对特定资源的精准防护。规则一定要存 Nacos 做持久化,别让 Dashboard 重启把你的防护规则一锅端了。