☰
第23课:Sentinel熔断降级、系统自适应保护、集群限流
2026/10/13 3:04:49 网站建设 项目流程

文章目录

    • 一、开篇:流控之后,还需要熔断
    • 二、熔断规则核心参数解析
      • 2.1 DegradeRule的完整字段
      • 2.2 三种熔断策略对照
    • 三、慢调用比例熔断实战
      • 3.1 配置示例
      • 3.2 熔断触发条件
      • 3.3 熔断后的行为
      • 3.4 生产配置建议
    • 四、异常比例与异常数熔断实战
      • 4.1 异常比例熔断
      • 4.2 异常数熔断
      • 4.3 三种策略组合使用
    • 五、断路器状态机与DegradeSlot源码解析
      • 5.1 两种断路器实现
      • 5.2 DegradeSlot的entry与exit
      • 5.3 tryPass的核心逻辑
      • 5.4 状态转换的触发时机
      • 5.5 熔断器状态机图示
    • 六、系统自适应保护
      • 6.1 核心理念
      • 6.2 五种系统规则阈值类型
      • 6.3 配置示例
      • 6.4 Load保护的特殊逻辑
    • 七、集群限流
      • 7.1 为什么需要集群限流
      • 7.2 Token Server与Token Client
      • 7.3 集群流控规则配置
      • 7.4 Token Server部署方式
      • 7.5 Token Server高可用方案
    • 八、踩坑指南
      • 坑一:熔断规则count配反了
      • 坑二:熔断后没有降级响应
      • 坑三:熔断恢复后立即再次熔断
      • 坑四:系统自适应保护的Load阈值不生效
      • 坑五:集群限流Token Server不可用导致全局限流失效
      • 坑六:集群限流规则ID不唯一导致规则冲突
    • 九、课后作业
    • 十、下节预告
  • 🔗《最新版 SpringCloud 2025 从入门到实战》系列课程导航

适配版本:Sentinel 1.8.9、Spring Cloud Alibaba 2025.1.0.0、Spring Cloud 2025.1.3(Oakwood)、Spring Boot 4.0.8、JDK 21
课程定位:熔断限流容错阶段进阶,从熔断三种策略到系统自适应保护,从状态机源码到集群限流部署,构建完整的容错闭环

一、开篇:流控之后,还需要熔断

第22课我们完成了Sentinel流控的全方位实战:直接/关联/链路三种模式、快速失败/Warm Up/排队等待三种效果、热点参数限流、规则持久化到Nacos。流控解决的是“流量太大”的问题——当请求量超过阈值时,主动拒绝或排队,保护系统不被过载压垮。

但流控有一个前提假设:被限流的资源本身是健康的。如果下游服务已经出现故障(如响应时间从50ms飙升到5秒),继续向它发送请求,即使QPS在阈值以内,也会导致线程被阻塞、调用链被拖垮。这时候需要的是熔断——检测到下游服务异常后,主动切断调用,让上游服务快速失败或返回降级响应。

熔断降级作为保护自身的手段,通常在客户端(调用端)进行配置。熔断器的工作模式是三个状态的循环:关闭 → 打开 → 半开 → 关闭。关闭状态下正常放行;打开状态下所有请求立即失败(不发送到下游);半开状态下放行少量请求探测下游是否恢复。

本课将从熔断的三种策略讲起,深入DegradeSlot的源码和断路器状态机,实战慢调用比例、异常比例、异常数三种熔断规则的配置,然后讲解系统自适应保护的五种阈值类型,最后完成集群限流的Token Server部署。

二、熔断规则核心参数解析

2.1 DegradeRule的完整字段

熔断降级规则由DegradeRule类定义,包含以下核心字段:

publicclassDegradeRuleextendsAbstractRule{privateintgrade;// 熔断策略类型privatedoublecount;// 阈值(含义取决于grade)privateinttimeWindow;// 熔断后恢复时间(秒)privateintminRequestAmount;// 最小请求数(防止统计噪声)privatedoubleslowRatioThreshold;// 慢请求比例阈值(仅RT模式)privateintstatIntervalMs;// 统计窗口长度(毫秒,默认1000ms)}

2.2 三种熔断策略对照

策略grade值count含义触发条件适用场景
慢调用比例0(DEGRADE_GRADE_RT)慢调用临界RT(毫秒)统计窗口内请求数≥minRequestAmount,且慢调用比例≥slowRatioThreshold下游服务响应变慢
异常比例1(DEGRADE_GRADE_EXCEPTION_RATIO)异常比例阈值(0.0~1.0)统计窗口内请求数≥minRequestAmount,且异常比例≥count下游服务异常率升高
异常数2(DEGRADE_GRADE_EXCEPTION_COUNT)每秒异常数阈值统计窗口内异常数≥count快速失败,对异常数敏感

关键理解:从Sentinel 1.8开始,RT模式不再看“平均RT”,而是看“慢请求比例”——统计窗口内,响应时间超过count的请求占比超过slowRatioThreshold时才触发熔断。这比1.7之前的“连续N个请求都超时”更科学,避免了因个别慢请求导致的误熔断。

三、慢调用比例熔断实战

3.1 配置示例

@ConfigurationpublicclassDegradeRuleConfig{@PostConstructpublicvoidinitDegradeRules(){List<DegradeRule>rules=newArrayList<>();// 慢调用比例熔断DegradeRuleslowRule=newDegradeRule("callPaymentService").setGrade(RuleConstant.DEGRADE_GRADE_RT)// 慢调用比例模式.setCount(1000)// 慢调用RT阈值:1000ms.setSlowRatioThreshold(0.5)// 慢调用比例阈值:50%.setMinRequestAmount(5)// 最小请求数:5.setTimeWindow(10)// 熔断时长:10秒.setStatIntervalMs(10000);// 统计窗口:10秒rules.add(slowRule);DegradeRuleManager.loadRules(rules);}}

配置解析:

参数值含义
count1000响应时间超过1000ms的请求记为“慢调用”
slowRatioThreshold0.5慢调用比例超过50%触发熔断
minRequestAmount5统计窗口内至少有5个请求才做判断
timeWindow10熔断后10秒内请求快速失败
statIntervalMs10000统计窗口为10秒

3.2 熔断触发条件

触发熔断的完整条件(三个条件同时满足):

  1. 统计窗口(statIntervalMs)内,总请求数 ≥minRequestAmount
  2. 慢调用(RT >count)的比例 ≥slowRatioThreshold
  3. 当前断路器状态为CLOSED

3.3 熔断后的行为

熔断触发后,断路器从CLOSED变为OPEN:

  • OPEN状态:timeWindow秒内,所有请求被立即拒绝,抛出DegradeException
  • HALF_OPEN状态:timeWindow到期后,断路器进入半开状态,放行一个探测请求
    • 如果探测请求的RT <count(不是慢调用),断路器恢复到CLOSED
    • 如果探测请求仍然是慢调用,断路器重新回到OPEN,重新计时

3.4 生产配置建议

场景count(RT阈值)slowRatioThresholdtimeWindow
支付/订单等核心服务800ms0.330秒
商品查询等一般服务500ms0.510秒
日志上报等非核心服务2000ms0.85秒

黄金法则:count应设置为下游服务P99响应时间的1.5~2倍。如果下游P99是300ms,count设为500-600ms。设置过低会导致正常的慢请求被误判,设置过高则失去熔断的意义。

四、异常比例与异常数熔断实战

4.1 异常比例熔断

DegradeRuleexceptionRatioRule=newDegradeRule("callUserService").setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_RATIO)// 异常比例模式.setCount(0.5)// 异常比例阈值:50%.setMinRequestAmount(10)// 最小请求数:10.setTimeWindow(30)// 熔断时长:30秒.setStatIntervalMs(10000);// 统计窗口:10秒

触发条件:统计窗口内请求数 ≥ 10,且异常比例 ≥ 50%。

异常比例的统计范围:异常降级仅针对业务异常,对Sentinel限流降级本身的异常(BlockException)不生效。需要通过Tracer.trace(ex)记录业务异常,或使用@SentinelResource注解(会自动统计)。

4.2 异常数熔断

DegradeRuleexceptionCountRule=newDegradeRule("callInventoryService").setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_COUNT)// 异常数模式.setCount(20)// 异常数阈值:20.setTimeWindow(60)// 熔断时长:60秒.setStatIntervalMs(60000);// 统计窗口:60秒

触发条件:统计窗口内异常数 ≥ 20。

异常比例 vs 异常数:异常比例适用于请求量大且相对稳定的场景(比例更有统计意义);异常数适用于请求量小或波动大的场景(比例容易被少数请求扭曲)。

4.3 三种策略组合使用

同一个资源可以配置多条熔断规则,任意一条触发即熔断:

List<DegradeRule>rules=newArrayList<>();rules.add(newDegradeRule("callUserService").setGrade(RuleConstant.DEGRADE_GRADE_RT).setCount(500).setSlowRatioThreshold(0.6).setMinRequestAmount(10).setTimeWindow(30));rules.add(newDegradeRule("callUserService").setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_RATIO).setCount(0.5).setMinRequestAmount(10).setTimeWindow(30));rules.add(newDegradeRule("callUserService").setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_COUNT).setCount(30).setTimeWindow(30));DegradeRuleManager.loadRules(rules);

五、断路器状态机与DegradeSlot源码解析

5.1 两种断路器实现

Sentinel的断路器分为两类:

断路器类适用策略统计维度
ResponseTimeCircuitBreaker慢调用比例慢调用数、总请求数
ExceptionCircuitBreaker异常比例、异常数异常数、总请求数

5.2 DegradeSlot的entry与exit

DegradeSlot是ProcessorSlotChain的最后一环,负责熔断规则的校验:

publicclassDegradeSlotextendsAbstractLinkedProcessorSlot<DefaultNode>{@Overridepublicvoidentry(Contextcontext,ResourceWrapperresourceWrapper,DefaultNodenode,intcount,booleanprioritized,Object...args){// 执行熔断检查performChecking(context,resourceWrapper);// 继续执行(实际上已无下一个Slot)fireEntry(context,resourceWrapper,node,count,prioritized,args);}privatevoidperformChecking(Contextcontext,ResourceWrapperr)throwsBlockException{List<CircuitBreaker>circuitBreakers=DegradeRuleManager.getCircuitBreakers(r.getName());if(circuitBreakers==null||circuitBreakers.isEmpty())return;for(CircuitBreakercb:circuitBreakers){if(!cb.tryPass(context)){thrownewDegradeException(cb.getRule().getLimitApp(),cb.getRule());}}}}

执行时机:DegradeSlot.entry()在请求进入时执行,检查断路器是否允许通过。DegradeSlot.exit()在请求完成时执行,触发circuitBreaker.onRequestComplete()回调,更新统计指标并判断是否触发状态转换。

5.3 tryPass的核心逻辑

publicbooleantryPass(Contextcontext){// 1. 当前状态为CLOSED → 允许通过if(currentState.get()==State.CLOSED){returntrue;}// 2. 当前状态为OPEN → 检查是否已过熔断时长if(currentState.get()==State.OPEN){// 熔断时长已到 → 尝试转换为HALF_OPENif(currentState.compareAndSet(State.OPEN,State.HALF_OPEN)){// 成功转换,放行探测请求returntrue;}// 熔断时长未到 → 拒绝returnfalse;}// 3. 当前状态为HALF_OPEN// 只放行一个探测请求,其他请求拒绝returncurrentState.compareAndSet(State.HALF_OPEN,State.HALF_OPEN);}

5.4 状态转换的触发时机

状态转换触发条件执行位置
CLOSED → OPEN统计窗口内慢调用/异常比例超过阈值onRequestComplete()
OPEN → HALF_OPENtimeWindow到期tryPass()
HALF_OPEN → CLOSED探测请求成功onRequestComplete()
HALF_OPEN → OPEN探测请求失败(慢调用或异常)onRequestComplete()

5.5 熔断器状态机图示

┌──────────┐ │ CLOSED │ 正常状态,所有请求通过 │ (关闭) │ 统计慢调用/异常指标 └────┬─────┘ │ 触发熔断条件 │ (慢调用比例 ≥ slowRatioThreshold │ 或 异常比例 ≥ count │ 或 异常数 ≥ count) ▼ ┌──────────┐ │ OPEN │ 熔断状态,所有请求被拒绝 │ (打开) │ 返回 DegradeException └────┬─────┘ │ timeWindow 到期 ▼ ┌──────────┐ │HALF_OPEN │ 半开状态,放行一个探测请求 │ (半开) │ └────┬─────┘ │ ├─── 探测请求成功(RT < count 且无异常) │ → 恢复 CLOSED │ └─── 探测请求失败(慢调用或异常) → 重新 OPEN,重新计时

六、系统自适应保护

6.1 核心理念

Sentinel系统自适应保护从整体维度对应用入口流量进行控制,结合应用的Load、总体平均RT、入口QPS和线程数等几个维度的监控指标,让系统的入口流量和系统的负载达到一个平衡。

传统方案根据load1阈值来决定是否限流,存在两个问题:负载是“果”而非“因”,调整通过率后需要等待一段时间才能看到效果;下游恢复后负载仍然很高,恢复缓慢。Sentinel借鉴了TCP BBR的思想:用load1作为启动控制流量的值,而允许通过的流量由处理请求的能力(响应时间、当前QPS)来决定。

6.2 五种系统规则阈值类型

类型触发条件说明
Loadload1 > 阈值 且 并发线程数 > 系统容量仅对Linux/Unix生效,系统容量 = maxQps × minRt
CPU使用率CPU使用率 > 阈值取值范围0.0~1.0
平均RT所有入口流量的平均RT > 阈值单位毫秒
并发线程数所有入口流量的并发线程数 > 阈值全局维度
入口QPS所有入口流量的QPS > 阈值全局维度

重要限制:系统规则是应用整体维度的,不是资源维度的,且仅对入口流量(EntryType.IN)生效。

6.3 配置示例

@ConfigurationpublicclassSystemRuleConfig{@PostConstructpublicvoidinitSystemRules(){List<SystemRule>rules=newArrayList<>();// CPU使用率超过80%触发系统保护SystemRulecpuRule=newSystemRule();cpuRule.setHighestCpuUsage(0.8);rules.add(cpuRule);// 入口QPS超过10000触发系统保护SystemRuleqpsRule=newSystemRule();qpsRule.setQps(10000);rules.add(qpsRule);// 并发线程数超过500触发系统保护SystemRulethreadRule=newSystemRule();threadRule.setMaxThread(500);rules.add(threadRule);SystemRuleManager.loadRules(rules);}}

6.4 Load保护的特殊逻辑

Load保护的触发条件较为特殊,需要同时满足两个条件:

  1. 当前系统load1 >highestSystemLoad阈值
  2. 当前并发请求数 > 系统容量(系统容量 =maxQps × minRt)

为什么需要两个条件?仅凭load1判断会误伤——load1高可能是由于I/O等待而非CPU竞争。加上并发数的判断后,只有在“系统确实处理不过来”时才触发保护,避免了对正常高负载的误判。

Load阈值设定参考值:CPU cores × 2.5。例如4核机器,Load阈值设为10。

七、集群限流

7.1 为什么需要集群限流

单机限流存在一个根本问题:流量分配不均匀。假设集群有10台机器,每台限流10 QPS,理论上集群总量100 QPS。但实际流量可能不均匀——某些机器收到15 QPS被限流,而其他机器只收到5 QPS,导致“总量没到,但部分机器已经限流”。

集群限流可以精确控制整个集群的调用总量,确保不管流量如何分布,总QPS始终不超过预设阈值。

7.2 Token Server与Token Client

集群流控中有两种身份:

身份职责
Token Server集群流控服务端,处理来自Token Client的请求,根据规则判断是否发放令牌
Token Client集群流控客户端,向Token Server申请令牌,根据返回结果决定是否限流

通信机制:Token Client向Token Server发送令牌申请请求,Token Server根据当前集群的QPS统计和规则阈值,判断是否发放令牌。如果发放,Client放行请求;如果不发放,Client执行本地限流逻辑。

7.3 集群流控规则配置

FlowRule添加集群模式:

ClusterFlowConfigclusterConfig=newClusterFlowConfig().setFlowId(1L)// 全局唯一的规则ID.setThresholdType(ClusterRuleConstant.FLOW_THRESHOLD_GLOBAL)// 全局阈值模式.setFallbackToLocalWhenFail(true);// Token Server不可用时回退到本地限流FlowRulerule=newFlowRule("cluster-resource").setGrade(RuleConstant.FLOW_GRADE_QPS).setCount(1000)// 集群总QPS阈值.setClusterMode(true).setClusterConfig(clusterConfig);FlowRuleManager.loadRules(Collections.singletonList(rule));

关键字段说明:

字段含义说明
flowId全局唯一规则ID由管控端分配,保持全局唯一
thresholdType阈值模式0=单机均摊,1=全局阈值
fallbackToLocalWhenFail回退策略Token Server不可用时是否回退到本地限流

单机均摊 vs 全局阈值:单机均摊模式下,配置的阈值等同于单机承受限额,Token Server根据连接数计算总阈值(3个Client连接,单机阈值10,总阈值30);全局模式下,配置的阈值就是整个集群的总阈值。

7.4 Token Server部署方式

方式一:独立模式。单独部署一个Token Server进程,所有Token Client连接到它:

ClusterTokenServertokenServer=newSentinelDefaultTokenServer();tokenServer.start();

方式二:嵌入模式。集群中选择一个节点同时作为Token Server和Token Client:

// 在应用启动时,将当前节点嵌入为Token ServerClusterTokenServertokenServer=newSentinelDefaultTokenServer();tokenServer.start();// 同时将当前节点作为Token ClientClusterStateManager.applyState(ClusterStateManager.CLUSTER_CLIENT);

生产建议:独立模式更稳定(Token Server故障不影响业务节点),但需要额外的部署资源;嵌入模式节省资源,但Token Server节点的故障会影响整个集群的限流功能。推荐使用独立模式,并通过Nacos实现Token Server的自动选举和故障转移。

7.5 Token Server高可用方案

Token Server本身如果成为单点,整个集群限流功能就会失效。高可用方案如下:

方案一:Nacos自主选举。借助Nacos注册中心,集群中所有节点注册到Nacos,选取注册列表中第一个节点作为Token Server。如果Token Server不可用,重新选举。

方案二:Sentinel Dashboard指定。通过Sentinel Dashboard手动指定某个节点为Token Server,其他节点作为Token Client。Dashboard提供了集群流控的配置界面。

方案三:Fallback保护。配置fallbackToLocalWhenFail=true,当Token Client无法连接Token Server时,自动回退到本地单机限流模式,保证服务不会因Token Server故障而完全不可用。

八、踩坑指南

坑一:熔断规则count配反了

现象:慢调用比例模式下,count设为0.5,但期望的是RT阈值500ms。

原因:混淆了count和slowRatioThreshold。慢调用比例模式下,count是RT阈值(毫秒),slowRatioThreshold才是慢调用比例阈值(0.0~1.0)。

解决:setCount(500)设置RT阈值,setSlowRatioThreshold(0.5)设置比例阈值。

坑二:熔断后没有降级响应

现象:熔断触发后,返回的是Sentinel默认的DegradeException,前端无法处理。

原因:未配置blockHandler或BlockExceptionHandler。

解决:使用@SentinelResource的blockHandler指定降级方法,或实现BlockExceptionHandler接口统一处理(第22课6.2节)。

坑三:熔断恢复后立即再次熔断

现象:熔断时长到期后,第一个探测请求通过,但随后立即再次熔断。

原因:下游服务的问题没有真正恢复,探测请求仍然是慢调用或异常。

解决:这是正常行为——熔断器的半开状态本身就是“试探性恢复”。应检查下游服务是否真正恢复健康,或适当增加timeWindow给下游更长的恢复时间。

坑四:系统自适应保护的Load阈值不生效

现象:配置了Load保护规则,但系统load1已经很高,仍然没有触发限流。

原因:Load保护需要同时满足“load1 > 阈值”和“并发线程数 > 系统容量”两个条件。如果并发数不够高,即使load1很高也不会触发。

解决:检查并发线程数是否超过maxQps × minRt。如果并发数不足,Load保护不会生效——这是设计行为,避免对正常高负载的误判。

坑五:集群限流Token Server不可用导致全局限流失效

现象:Token Server宕机后,所有Token Client的集群限流完全失效,流量全部放行。

原因:未配置fallbackToLocalWhenFail=true。

解决:始终设置fallbackToLocalWhenFail=true,确保Token Server不可用时自动回退到本地单机限流,保证基本的保护能力。

坑六:集群限流规则ID不唯一导致规则冲突

现象:多个集群限流规则配置了相同的flowId,导致限流行为异常。

原因:flowId是全局唯一的,不能重复。

解决:由管控端统一分配flowId,或使用数据库自增ID确保唯一性。

九、课后作业

作业一:为callUserService资源配置慢调用比例熔断:RT阈值800ms,慢调用比例阈值50%,最小请求数5,熔断时长15秒。模拟下游服务响应缓慢(Thread.sleep(1000)),验证熔断触发和恢复。

作业二:为callPaymentService资源配置异常比例熔断:异常比例阈值40%,最小请求数10,熔断时长30秒。通过人为抛出异常验证熔断触发,观察异常比例从上升到达标再到熔断的完整过程。

作业三:配置系统自适应保护规则,CPU使用率阈值0.8,入口QPS阈值5000,并发线程数阈值300。使用压测工具施加压力,观察哪个维度的阈值最先触发。

作业四:部署Token Server(独立模式),配置集群限流规则(全局阈值模式,QPS=1000)。启动两个Token Client实例,验证集群总QPS精确控制在1000以内。然后停止Token Server,验证fallbackToLocalWhenFail回退机制。

作业五(进阶):阅读DegradeSlot和ResponseTimeCircuitBreaker源码,画出慢调用比例熔断的完整状态转换图,标注每个状态转换的触发条件和执行方法。

十、下节预告

第24课将进入Sentinel网关限流、授权规则 & 生产级容错方案。内容包括Gateway网关专属限流(Sentinel集成Gateway)、黑白名单授权规则、IP限流、用户维度限流、规则Nacos持久化的完整实战,以及生产环境的故障演练和容错体系搭建。本课完成了Sentinel的熔断降级和系统保护,第24课将把Sentinel的能力扩展到网关层,并构建完整的生产级容错体系。

🔗《最新版 SpringCloud 2025 从入门到实战》系列课程导航

去订阅

第一部分:微服务前置基础 & 新版环境搭建(第1-5课)
第二部分:注册中心核心(Nacos 最新版)(第6-9课)
第三部分:配置中心核心(Nacos配置中心)(第10-12课)
第四部分:服务通信核心(OpenFeign + LoadBalancer)(第13-16课)
第五部分:网关核心(SpringCloud Gateway 新版)(第17-20课)
第六部分:熔断、限流、降级(Sentinel 新版)(第21-24课)
第七部分:微服务监控、链路追踪、日志体系(第25-28课)
第八部分:微服务高阶特性 & 分布式核心能力(第29-31课)
第九部分:企业级完整项目实战 & 架构复盘(第32-35课)

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询