2. API熔断机制基础:熔断器模式(Circuit Breaker Pattern)
2.1 熔断器模式的起源
熔断器模式(Circuit Breaker Pattern)最早由 Michael T. Nygard 在其著作 Release It! Design and Deploy Production-Ready Software 中提出。该模式借鉴了电气工程中“断路器”的原理:当电路过载或短路时,断路器自动跳闸,切断电流以保护整个系统。在软件架构中,熔断器用于保护服务调用链,防止级联故障(Cascading Failure)和雪崩效应。
在模型风险管理(MRM)场景中,API 熔断机制的核心目标是:当模型服务(如评分引擎、风险计算器)出现响应超时、错误率飙升或资源耗尽时,熔断器主动切断对该服务的调用,避免下游系统被拖垮,并为模型服务提供恢复时间。
核心原则:快速失败(Fail Fast)优于慢速崩溃(Slow Crash)。熔断器让系统在故障发生时迅速降级,而非让请求排队堆积直至资源耗尽。
2.2 熔断器的三种状态
熔断器是一个有限状态机,包含三种核心状态:关闭(Closed)、打开(Open) 和 半开(Half-Open)。下表总结了各状态的行为与转换条件:
| 状态 | 图标 | 行为描述 | 触发条件 | 对请求的处理 |
|---|---|---|---|---|
| Closed | 🟢 | 正常状态,熔断器闭合,请求正常通过 | 系统启动或故障恢复后 | 正常转发至模型服务 |
| Open | 🔴 | 熔断状态,请求被立即拒绝,不调用模型服务 | 失败计数超过阈值(如连续失败次数或错误率) | 直接返回降级响应或抛出异常 |
| Half-Open | 🟡 | 半开状态,允许少量探测请求通过,测试服务是否恢复 | Open 状态持续超时时间(如 30 秒)后自动进入 | 仅放行探测请求,其余仍被拒绝 |
2.3 状态转换图
下图展示了熔断器三种状态之间的完整转换路径,以及每个转换发生的条件:
2.4 状态转换的关键参数
熔断器的行为由以下核心参数控制,这些参数在 MRM 场景中需要根据模型服务的 SLA 进行调优:
| 参数名称 | 默认值 | MRM 推荐范围 | 说明 |
|---|---|---|---|
| failureThreshold | 5 | 3 ~ 10 | 连续失败次数阈值,达到后 Closed → Open |
| errorRateThreshold | 50% | 30% ~ 70% | 滑动窗口内错误率阈值,与 failureThreshold 二选一或组合使用 |
| timeout | 30 s | 10 s ~ 120 s | Open 状态持续时长,之后进入 Half-Open |
| halfOpenMaxRequests | 1 | 1 ~ 5 | Half-Open 状态下允许通过的探测请求数量 |
| slidingWindowSize | 10 | 10 ~ 100 | 统计错误率时使用的滑动窗口大小(请求数) |
2.5 熔断器在 MRM 中的典型应用流程
在模型风险管理中,熔断器通常嵌入在 API 网关或服务网格层,对模型推理端点进行保护。以下是一个典型的调用流程:
- 请求到达:客户端请求模型推理 API(如信用评分、违约概率计算)。
- 熔断器检查:熔断器判断当前状态:
- 若为 Closed:允许请求通过,调用模型服务。
- 若为 Open:直接返回降级响应(如缓存结果、默认值或错误提示),不调用模型服务。
- 若为 Half-Open:仅放行探测请求,其余请求仍被拒绝。
- 结果记录:模型服务返回后,熔断器记录成功或失败,更新滑动窗口统计。
- 状态迁移:根据统计结果判断是否触发状态转换。
MRM 实践建议:对于关键模型(如巴塞尔协议下的风险加权资产计算),建议将熔断器的 failureThreshold 设低(如 3 次),并配合缓存降级策略,确保在模型服务不可用时仍能返回保守估计值,避免业务中断。
2.6 熔断器 vs. 重试 vs. 限流
熔断器常与重试(Retry)和限流(Rate Limiting)混淆。下表清晰区分了三者的定位:
| 机制 | 目标 | 适用场景 | 风险 |
|---|---|---|---|
| 熔断器 | 防止级联故障,保护调用方和被调用方 | 服务持续不可用、错误率飙升 | 过度熔断可能导致可用性下降 |
| 重试 | 处理瞬时故障,提高成功率 | 网络抖动、超时重试 | 无限制重试会加剧负载 |
| 限流 | 控制请求速率,保护后端资源 | 突发流量、资源瓶颈 | 配置不当会误杀正常请求 |
常见误区:不要将熔断器与重试混用而不加限制。例如,在 Closed 状态下重试失败请求,可能导致失败计数快速膨胀,触发不必要的熔断。正确的做法是:重试应独立于熔断器统计,或仅在熔断器 Closed 状态下允许有限次数的重试。