企业级 AI API 高可用与故障演练 2026:双供应商架构、主备切换、故障注入实战

企业级 AI API 高可用与故障演练 2026:双供应商架构、主备切换、故障注入实战

TL;DR — 高可用是演练出来的,不是配出来的。这篇不再列”5 种 fallback 方案”,而是给一份故障演练剧本:双供应商主备架构怎么落地,健康检查和熔断阈值怎么定才不会误切,怎么用 toxiproxy 注入六类故障,Game Day 流程模板,切换时一定会撞到的协议不兼容陷阱。

我见过的大部分团队,fallback 代码上线后从来没被真实流量触发过。第一次触发,通常就是生产事故现场。

为什么”配了 fallback”≠“高可用”

高可用方案怎么设计那篇讲过 fallback、负载均衡、熔断这些机制怎么搭。但工程上有一条坎,几乎所有团队都会栽:写了代码不等于跑通过。

2026 年 4 月 Anthropic 接连出现多次故障(4 月 7 日 Claude.ai 登录与会话约 40 分钟受影响、4 月 15 日 Claude.ai/API/Claude Code 三处错误率攀升、4 月 28 日 Claude.ai/Claude Code/API 同时不可用约 80 分钟),翻车的不只是没做 fallback 的团队,做了 fallback 但从没演练过的同样翻。复盘里常见的几个画面:

  • 健康检查阈值太宽(要连续 10 次失败才熔断),故障已经持续 8 分钟,流量还在硬刚主供应商
  • 备用模型从来没承接过满量流量,切过去自己也被打到 429
  • tool call 字段两边不一致,切换的那一瞬间所有 agent 调用全挂
  • 监控面板看上去是绿的,因为 health check 走的是 /v1/models 这种轻量端点,真实的 /v1/messages 已经在喷 503

这些不是 fallback 方案的问题。是 fallback 路径没被当成”和主路径同等重要的代码”来对待。

Chaos Engineering / Game Day 就是干这件事:在你主动选的时间窗里,让备用路径真的跑一次,把隐患翻出来。比凌晨被 PagerDuty 叫醒翻强一百倍。

双供应商架构的两种形态

Active-Passive(主备):默认选这个

主供应商承担 100% 流量,备用空转、只接受健康检查。触发条件满足时整体切到备用。

客服机器人、内容生成、Agent 工作流、批处理,这几类业务直接选主备就行。工程成本最低,回归测试也好控制。

落地时几个关键参数:

决策项推荐值取舍说明
健康检查频率主供应商 5s/次,备用 30s/次主侧密一点保证及时发现,备侧稀一点省成本
健康检查端点/v1/messages 真实推理 + 极短 prompt不要用 /v1/models 这种 metadata 端点,故障时它依然 200
熔断窗口30s 内错误率 > 50% 触发太短会被瞬时抖动误触发,太长拉高用户感知延迟
熔断恢复半开探测 1 分钟,10% 流量灰度回切直接 100% 切回主侧容易二次雪崩
切换决策权自动 + 人工 override大故障时人工要能强制保持在备用侧,防止反复抖动

Active-Active(双活):只在两类场景下用

两侧都承担流量(典型 70/30 或 50/50),按权重路由。

值得做的场景就两种:业务对首 token 延迟 SLO 极敏感(< 300ms),任何一次切换的延迟尖峰都不能接受;或者单一供应商的配额根本不够你的峰值流量,必须并行分摊。

代价不小。所有 prompt 改一次要两边都验证、新模型上线要做双侧基准回归、token 账单按供应商分桶记账、每个 tool call 都要做协议适配。工程负担基本翻倍。业务对 100ms 不敏感的话,主备加快速切换是更划算的选择。

健康检查和熔断:阈值怎么定才不会误切

健康检查最容易犯的错是用错端点。/v1/models 这类 metadata 端点在故障期间往往还能返回 200,因为它根本没走到推理后端。真实的健康检查得走一次最小化的真实推理:messages 接口发一个 “ping” prompt、max_tokens=5

阈值参考(不是教条,按自己业务调):

  • 错误率阈值:30 秒滑动窗口内 5xx + 429 + 超时合计占比 > 50% 触发熔断
  • 延迟阈值:P99 首 token 延迟 > 8 秒 且持续 60 秒触发熔断
  • 绝对失败次数下限:窗口内总请求 < 20 时不熔断,避免低流量时段的统计噪声
  • 熔断后冷却:60 秒最小冷却时间,避免快速 flapping

熔断恢复必须走半开探测:先放 5-10% 流量到主侧,观察 1-2 分钟错误率回到正常,再灰度到 50%,再正常才 100% 切回。一刀切回是最容易引发二次雪崩的操作。

各家报错码语义、哪些可重试哪些不可,AI API 报错大全 这份手册可以直接当 lookup 表用。

故障注入实战:六类必跑的故障

理论说完进实操。故障注入要覆盖六个维度,少一类就是漏了真实生产里会发生的某种事故。

1. 网络层超时

工具:toxiproxy 在 SDK 和真实 API 之间加代理。

# 注意:8474 是 toxiproxy daemon 的 admin 端口,listen 端口要另选(这里用 22220)
toxiproxy-cli create -l 127.0.0.1:22220 -u api.anthropic.com:443 anthropic
toxiproxy-cli toxic add anthropic -t latency -a latency=15000

业务侧把 SDK base_url 指到 127.0.0.1:22220,所有调用延迟 +15 秒。你的超时配置应该在 10 秒触发熔断切到备用。如果业务卡死等满 15 秒才返回失败,说明客户端超时设漏了。

2. TCP RST / 连接拒绝

toxiproxy-cli toxic add anthropic -t reset_peer -a timeout=1000

连接直接被打断。看连接池能不能自动重建、重试逻辑会不会进死循环。

3. HTTP 5xx 喷射

需要一个 mock provider,按比例返回 503。最简版本 30 行 Python:

from fastapi import FastAPI, Request, Response
import random
app = FastAPI()

@app.post("/v1/messages")
async def msg(req: Request):
    if random.random() < 0.3:
        return Response(status_code=503)
    return forward_to_real_anthropic(await req.body())

把 SDK base_url 指向 mock,看 30% 错误率下熔断会不会按预期触发。

4. 429 限速

返回标准 429 + retry-after header。看指数退避有没有生效、有没有触发”连续 429 就切到备用”的策略。

5. 慢响应(不超时但 P99 翻倍)

注入 3-5 秒固定延迟(不到超时阈值)。这一类最容易被漏掉:监控里”错误率正常”,但用户感知延迟翻倍。看延迟 SLO 告警能不能识别出来。

6. 流式断流

stream 中途切断连接,模拟 token 流到一半网络抖动。这类故障只能在 SDK 层注入。看客户端会不会重新发起完整请求,还是把残缺响应直接抛给用户。

注入比例从 1% 起步,逐步加到 10%、30%、50%。每一档观察 5-10 分钟,记下熔断触发时间、备用承接表现、用户侧错误率。

Game Day 流程模板

把上面六类组织成一次完整演练,2-3 小时的窗口够用。模板:

阶段时长操作关键验证点
准备30 min通告相关团队、开监控大屏、确认回滚开关可用所有人在同一个频道、回滚命令拷贝待用
注入 115 min主供应商注入 30% 5xx熔断在 30s 内触发,备用承接
观察15 min切到备用后观察用户侧指标错误率回落、P99 延迟在 SLO 内
注入 215 min备用供应商也注入 20% 5xx二级 fallback 触发、降级提示是否给到用户
恢复15 min解除注入、观察半开探测半开窗口是否正确执行,没有 flapping
注入 315 min慢响应注入(+5s 延迟)延迟告警触发、是否需要降级
注入 415 min429 限速 + 流式断流组合复合故障下系统行为是否可解释
复盘30 min汇总数据、记录所有”原以为不会发生”的事输出 action items 到 issue tracker

复盘环节最重要的产出是一份”原以为 X 但实际 Y”清单。每一条都对应一个潜在的生产隐患。

切换瞬间的协议兼容陷阱

不同供应商的 API 表面都是 OpenAI-like,但细节差异会在切换那一瞬间集中爆出来。

tool call schema 不一致:Anthropic 用 input_schema,OpenAI 用 parameters,字段嵌套结构也不同。同一个 tool 定义在两边要么分别维护,要么加一层适配。

stop sequence 行为:OpenAI 把 stop sequence 当”输出到这里停止且不包含”,部分模型会把 stop sequence 本身一起返回。业务如果依赖 stop 后的精确截断,切换瞬间整行错位。

system prompt 上限:不同模型对 system prompt 的有效长度处理不一样。一段 10K 的 system prompt 在某些模型上会被静默截断,行为就变了。

token 计费差异:同一段输入文本,不同 tokenizer 产生的 token 数能差 15-30%。切到备用后账单突然飙升,不是流量大了,是计价口径不同。

流式响应格式:SSE 事件结构、role / delta / content_block 字段差异。前端如果硬解析两边的不同结构,切换瞬间渲染就崩。

防御方式只有一个:抽出一层协议适配层,业务代码只看适配层的标准化输出。这一层的回归测试比业务测试更重要,因为它就是高可用切换的最后一道防线。

Claude 这家具体的报错码语义和重试边界,Claude API 报错指南 是配套的细节手册。

用聚合平台做”高可用即服务”

自建上面这一整套至少要一个全职 SRE 长期维护。对中小团队,更务实的做法是把高可用逻辑外包给聚合平台。

Ofox.ai 这类聚合平台在入口层统一做了多供应商路由、健康检查、熔断和自动 fallback。OpenAI 兼容接口的意思是:业务代码只调一个 api.ofox.ai,背后是 Claude Opus 4.7、GPT-5.5、Gemini 3.1 Pro Preview、Kimi K2.6、MiniMax M2.7、DeepSeek V4 Pro 这十多家的切换池。某一家宕机,平台层切,业务侧透明。

这不等于”不需要 Game Day 了”。应用侧的降级表现你还是得演练。省下来的是跨供应商的协议适配、健康检查、熔断状态机这些大头工作量。

业务还在快速迭代、SRE 资源紧的时候,先用聚合平台兜住可用性,等规模和场景明确了再决定要不要自建。聚合平台和直连官方的稳定性差异,OfoxAI vs OpenRouter 对比 有更细的横评。

上线前必跑的 12 项 chaos 用例

打印贴墙的版本:

  1. 主供应商 30% 5xx 注入 → 熔断 30s 内触发
  2. 主供应商 30% 429 注入 → 切到备用 + 客户端退避生效
  3. 主 + 备同时 20% 5xx → 二级降级 / 降级提示给到用户
  4. 主供应商 +5s 延迟(不超时)→ 延迟告警触发,但不误熔断
  5. 主供应商 TCP RST → 连接池重建、无死循环重试
  6. 主供应商 stream 断流 → 客户端正确处理(重试或友好报错)
  7. 主供应商全宕(100% 5xx) → 30s 内完全切到备用
  8. 故障恢复 → 半开探测 1 分钟、灰度回切,无 flapping
  9. 跨供应商 tool call 调用 → 字段适配层正确转换
  10. 跨供应商 token 计费一致性 → 账单数据按供应商分桶记录
  11. 健康检查端点降级(用 /v1/messages 真实推理) → 真故障时能识别
  12. 人工 override 锁定备用侧 → 自动切换不会反复抖动

每一项都写成可重复脚本,纳入 CI 或月度演练 checklist。


故障演练是用工程时间换 SLA 数字最直接的方式。每一次注入都是在生产事故之前提前付一笔保费。配了 fallback 但从没演练的系统,听上去有兜底,本质上还是把祈祷对象从”不要出故障”换成了”祈祷我的 fallback 代码真的能跑”。

下次有人在群里问”我们到底有没有做高可用”,把这份 12 项 checklist 发过去。能逐项打勾的才算。