2. 基础概念:熔断器模式原理与状态机
熔断器模式(Circuit Breaker Pattern)是分布式系统中防止级联故障的关键容错手段。其核心思想借鉴了电路工程中的断路器:当系统检测到连续故障时,自动“断开”对下游服务的调用,避免资源耗尽和故障扩散;待系统恢复后,再“闭合”电路恢复流量。
2.1 熔断器的三态状态机
熔断器维护一个有限状态机,包含三个核心状态:Closed(闭合)、Open(断开) 和 Half-Open(半开)。状态转换由预设的阈值和超时驱动。
| 状态 | 含义 | 调用行为 | 触发条件 |
|---|---|---|---|
| Closed | 电路闭合,正常调用 | 允许请求通过,统计失败率 | 初始状态;失败率低于阈值 |
| Open | 电路断开,拒绝调用 | 直接返回错误或降级响应,不发起实际调用 | 失败率超过阈值(如 50%) |
| Half-Open | 半开,试探性恢复 | 允许少量请求通过,检测下游是否恢复 | Open 状态持续超时(如 30 秒) |
关键指标:熔断器通常基于滑动窗口统计失败率。例如,在最近 10 秒内,若请求总数超过 20 且失败率 ≥ 50%,则状态从 Closed 转为 Open。
2.2 状态转换流程
- Closed → Open: 连续失败或失败率超过阈值,熔断器立即断开,阻止后续请求。
- Open → Half-Open: 经过预设的冷却时间(如 30 秒),熔断器允许一个探测请求通过。
- Half-Open → Closed: 探测请求成功,说明下游已恢复,熔断器闭合,恢复正常流量。
- Half-Open → Open: 探测请求失败,熔断器重新断开,重置冷却计时器。
设计要点:Half-Open 状态是熔断器模式的核心创新。它避免了在 Open 状态下永久拒绝请求,也防止了在未恢复时直接放行大量流量导致二次崩溃。
2.3 熔断器配置参数
实际生产环境中,熔断器需要根据服务特性精细调参。以下为典型配置项:
| 参数 | 说明 | 推荐值 |
|---|---|---|
failureThreshold |
触发 Open 的连续失败次数或失败率 | 5 次 或 50% |
successThreshold |
Half-Open 状态下探测成功次数,达到后转为 Closed | 2 次 |
timeout |
Open 状态持续时长,超时后进入 Half-Open | 30 秒 |
windowSize |
滑动窗口统计的时间范围 | 10 秒 |
minRequests |
触发熔断计算的最小请求数,避免低流量误判 | 5 |
常见误区:将熔断器超时时间设置过短(如 1 秒),会导致熔断器在 Open 状态频繁进入 Half-Open,造成“抖动”;设置过长(如 5 分钟)则延长服务不可用时间。建议根据下游服务平均恢复时间(MTTR)设定。
2.4 熔断器在微服务中的典型实现
以 Java 生态的 Resilience4j 为例,熔断器通过装饰器模式包装对外部服务的调用:
// Resilience4j 熔断器配置示例
CircuitBreakerConfig config = CircuitBreakerConfig.custom()
.failureRateThreshold(50) // 失败率阈值 50%
.waitDurationInOpenState(Duration.ofSeconds(30)) // Open 状态等待 30 秒
.slidingWindowSize(10) // 滑动窗口大小 10 个请求
.minimumNumberOfCalls(5) // 最小调用数 5
.permittedNumberOfCallsInHalfOpenState(3) // Half-Open 允许 3 个探测请求
.build();
CircuitBreaker circuitBreaker = CircuitBreaker.of("orderService", config);
// 使用熔断器保护调用
Supplier<String> decoratedSupplier = CircuitBreaker
.decorateSupplier(circuitBreaker, () -> orderService.getOrder(orderId));
// 执行调用,熔断器自动管理状态
String result = Try.ofSupplier(decoratedSupplier)
.recover(throwable -> "fallback response")
.get();
2.5 熔断器 vs. 重试 vs. 限流
熔断器常与重试、限流配合使用,但三者关注点不同:
| 模式 | 核心目标 | 触发条件 | 副作用 |
|---|---|---|---|
| 熔断器 | 防止级联故障,快速失败 | 连续失败或失败率超阈值 | 暂时切断流量,等待恢复 |
| 重试 | 补偿临时性故障 | 单个请求失败(如超时、网络抖动) | 可能增加下游压力,需配合退避策略 |
| 限流 | 保护系统不被突发流量冲垮 | 请求速率超过预设阈值 | 丢弃或排队请求,保证核心服务稳定 |
最佳实践:在熔断器 Open 状态下,应避免执行重试,否则会加剧下游压力。通常组合策略为:先限流 → 再熔断 → 熔断期间不重试 → 恢复后逐步放量。