《7.3 熔断降级:系统崩溃前的紧急逃生通道——让系统学会"装死"的艺术》
① 熔断降级の人类比喻
graph LR
A[程序员] -->|连续加班| B(情绪崩溃)
B -->|触发熔断| C[请假回家]
C -->|恢复期| D{尝试工作}
D -->|效率正常| E[继续搬砖]
D -->|效率低下| C
经典场景:
"当你的系统像连续加班三年的程序员,熔断就是强制它休年假,降级就是让它只处理核心需求(比如先别写PPT了)"
② Spring Cloud Alibaba Sentinel实战
代码:
// 前置:pom.xml添加依赖
// <dependency>
// <groupId>com.alibaba.cloud</groupId>
// <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
// <version>2021.0.4.0</version>
// </dependency>
@RestController
public class PaymentController {
// 定义支付资源(模拟支付接口)
@SentinelResource(value = "pay",
blockHandler = "blockHandlerForPay",
fallback = "fallbackForPay")
@GetMapping("/pay")
public String pay(@RequestParam String orderId) {
// 模拟20%概率失败
if (Math.random() > 0.8) {
throw new RuntimeException("银行接口超时");
}
return "订单" + orderId + "支付成功";
}
// 熔断降级处理(参数要和原方法一致)
public String blockHandlerForPay(String orderId, BlockException ex) {
return "系统繁忙,请稍后再试(熔断保护中)";
}
// 业务异常处理
public String fallbackForPay(String orderId, Throwable t) {
return "支付失败,已启动托底方案:" + t.getMessage();
}
}
// 熔断规则配置(可在控制台动态调整)
@PostConstruct
public void initRules() {
List<FlowRule> rules = new ArrayList<>();
FlowRule rule = new FlowRule();
rule.setResource("pay");
rule.setGrade(RuleConstant.FLOW_GRADE_QPS); // QPS阈值类型
rule.setCount(100); // 每秒最大100次调用
rules.add(rule);
FlowRuleManager.loadRules(rules);
DegradeRule degradeRule = new DegradeRule();
degradeRule.setResource("pay");
degradeRule.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_RATIO); // 异常比例
degradeRule.setCount(0.5); // 异常比例阈值50%
degradeRule.setTimeWindow(10); // 熔断时长10秒
degradeRule.setMinRequestAmount(20); // 最小请求数
DegradeRuleManager.loadRules(Collections.singletonList(degradeRule));
}
代码彩蛋:
启动后访问 http://localhost:8719/ 可进入Sentinel控制台,实时看到如下监控:
{
"resource": "pay",
"passQps": 85,
"blockQps": 15,
"rt": 230,
"exceptionCount": 18
}
③ 熔断状态机
stateDiagram-v2
[*] --> Closed
Closed --> Open: 失败率超过阈值
Open --> HalfOpen: 经过熔断时间窗
HalfOpen --> Closed: 探测请求成功
HalfOpen --> Open: 探测请求失败
④ 降级策略对比表
| 策略类型 | 适用场景 | 配置参数示例 | 大厂应用案例 |
|---|---|---|---|
| 慢调用比例 | 数据库查询类接口 | RT=500ms, 比例阈值=80% | 淘宝商品详情页查询 |
| 异常比例 | 第三方服务依赖 | 异常比例=50%, 时间窗=10s | 微信支付接口熔断 |
| 异常数 | 硬件故障场景 | 异常数=100次/分钟 | 银行核心交易系统 |
| 热点参数 | 高频访问特定数据 | 参数索引=0, QPS=100 | 微博热搜榜接口 |
⑤ 血泪案例库
案例1:某电商双十一雪崩事故
- 现象:支付接口响应时间从200ms飙升到8s
- 数据:订单流失率37%,损失¥2.3亿
- 尸检报告:
[ERROR] 级联故障链: |-- 支付服务超时 → 重试风暴 → DB连接池耗尽 |-- 风控服务阻塞 → 订单积压 → MQ堆积
案例2:社交平台明星官宣事件
- 措施:提前配置熔断规则
- 效果:
# 系统指标对比 峰值QPS: 85万 → 限流到50万 核心接口可用性: 63% → 99.98% 服务器成本: 节省40%
⑥ 高频面试八连击
-
熔断和降级的区别是什么?
答:熔断是自动故障保护(如保险丝),降级是主动功能裁剪(如关闭非核心服务)。熔断针对服务提供方,降级针对服务消费方。
-
Sentinel和Hystrix的优劣对比?
答:Sentinel支持实时规则调整、热点防护、系统自适应保护;Hystrix已停止更新但生态成熟。
-
如何设置合理的熔断阈值?
答:通过压测获取基线数据,通常:
- 慢调用比例:RT的2倍标准差
- 异常比例:历史平均值的1.5倍
-
熔断恢复机制如何设计?
答:采用指数退避算法,如初始10秒熔断,后续每次增加50%恢复时间,直到系统稳定。
-
如何测试熔断策略?
答:使用混沌工程工具(如ChaosBlade)模拟超时、异常,验证熔断触发和恢复逻辑。
-
微服务中如何全局管理熔断?
答:通过配置中心(Nacos)动态下发规则,结合Prometheus监控大盘实时调整。
-
熔断后的请求怎么处理?
答:四种策略:快速失败、返回托底数据、排队等待(需配合漏桶算法)、降级到备用服务。
-
如何避免无意义的熔断?
答:设置最小请求数阈值(如至少20次/秒),防止低流量时误触发。
⑦ 灵魂拷问:你的系统需要哪种逃生姿势?
决策树:
graph TD
A[是否核心链路?] -->|是| B{失败类型}
A -->|否| C[直接降级]
B -->|临时故障| D[熔断+自动恢复]
B -->|持久故障| E[降级+人工介入]
C --> F[返回缓存/默认值]
经典组合:
- 支付系统:熔断(异常比例)+ 降级(切换备用通道)
- 推荐系统:熔断(慢调用)+ 降级(返回通用推荐)
- 秒杀系统:熔断(QPS阈值)+ 降级(排队页面)
⑧ 自测实验:制造系统雪崩
步骤:
- 用JMeter以1000线程压测/pay接口
- 观察控制台熔断触发日志:
[WARN] Degrade rule triggered for resource pay |-- exceptionRatio: 62.3% |-- request count: 35 - 正常请求返回:
{ "code": 503, "msg": "系统繁忙,请稍后再试(熔断保护中)" }
进阶挑战:
调整熔断规则参数,观察系统恢复时间的变化规律
下一讲预告:
《7.4 限流算法:从漏桶到令牌桶的江湖恩怨》——手写分布式限流组件,用Guava和Redis分别实现百万级限流,带你破解高并发系统的流量密码!