什么是服务熔断
服务熔断(Circuit Breaker)的概念来源于电路中的保险丝 -- 当电流超过某个安全阈值时,保险丝自动熔断,切断电路,防止火灾。在微服务中,当某个服务的故障率超过阈值时,熔断器会"断开"该服务的调用链路,防止故障向下游蔓延。
为什么需要熔断
考虑这样一个场景:
客户端 → 服务A(网关层) → 服务B(实际业务层)
text
当服务 B 出现异常时:
- 服务 A 发起请求调用服务 B
- 服务 B 无法响应,服务 A 的请求线程被阻塞等待
- 更多的客户端请求涌入,每个请求都在等待服务 B 的响应
- 服务 A 的线程池被耗尽,无法处理任何请求
- 依赖服务 A 的其他服务也开始阻塞
- 级联故障 -- 整个系统崩溃
这就是所谓的雪崩效应。熔断器就是为了在步骤 2 之后截断故障链路而存在的。
熔断器的三种状态
熔断器使用有限状态机模型,包含三种状态:
成功率恢复正常
┌──────────────────────┐
│ │
▼ │
┌───────┐ 失败率超过阈值 ┌───────┐ 超时后尝试 ┌──────────┐
│ CLOSED │ ──────────────→ │ OPEN │ ──────────→ │HALF-OPEN │
│(正常) │ │(熔断) │ │ (半开) │
└───────┘ └───────┘ └──────────┘
▲ │
│ 尝试请求失败 │
└─────────────────────────────────────────────────┘
│ 尝试请求成功
└─────────────────────────────────────────────────→ CLOSED
text
CLOSED(关闭/正常)
正常工作状态。所有请求都正常通过,熔断器会持续统计请求的成功率和失败率。
OPEN(打开/熔断)
当失败率超过阈值(如 50%)时,熔断器打开。此时所有请求都不会被发送到目标服务,而是直接返回错误或执行降级逻辑。这样可以立即释放被阻塞的资源,防止级联故障。
HALF-OPEN(半开)
经过一段预设的恢复时间后,熔断器进入半开状态。此时会放行一个请求去探测目标服务是否已经恢复:
- 如果请求成功 -- 说明目标服务已恢复,熔断器切换回 CLOSED 状态
- 如果请求失败 -- 说明目标服务仍然异常,熔断器重新切换回 OPEN 状态
熔断的两个典型场景
场景一:过载保护
当服务 A 的某个节点不健康(CPU 过高、网络断开)时,负载均衡器通过熔断机制将该节点的权重调低或移除,将流量转发到健康节点 B。
用户请求 → 负载均衡 → [节点A(不健康)✗, 节点B(健康)✓]
↑ 熔断:不再向节点A发送请求
text
场景二:服务不可用保护
当服务 B 完全不可用时,服务 A 不应该继续发送请求并等待超时,而是应该立即熔断,执行降级逻辑,让服务 A 的其他功能继续正常运行。
服务A → 调用服务B → 服务B不可用
↓
熔断器打开 → 后续请求直接返回降级数据
服务A的其他接口继续正常工作
text
熔断与降级的关系
熔断和降级通常配合使用:
- 熔断是触发条件 -- 当失败率超过阈值时触发
- 降级是处理策略 -- 触发后返回什么数据给调用方
常见的降级策略:
| 策略 | 示例 |
|---|---|
| 返回默认值 | 推荐系统不可用时返回热门商品列表 |
| 返回缓存数据 | 价格服务不可用时返回上一次缓存的价格 |
| 返回简化数据 | 详情页完整数据不可用时返回基本信息 |
| 快速失败 | 直接返回错误信息,让用户稍后重试 |
熔断器需要配置的关键参数
| 参数 | 说明 | 典型值 |
|---|---|---|
| 超时时间 | 单个请求的超时时间 | 3-5 秒 |
| 失败率阈值 | 触发熔断的错误率百分比 | 50% |
| 恢复时间 | 熔断后多久尝试恢复 | 30 秒 |
| 最小请求数 | 统计失败率前的最小请求数 | 10-20 个 |
| 时间窗口 | 统计失败率的时间范围 | 1 分钟 |
↑