供应商故障时的降级:超时、限流与三层预案

周日晚八点供应商返回 503,AI 按钮把用户卡在半句上。本文给一人产品的三层降级预案:带抖动的超时重试、第二供应商与弱模型、模板缓存与人工队列,配熔断、429 与用户可见行为,用可用性、降级成功率、三层覆盖率三个算式做月度演练验收。

供应商的稳定性不由你决定,但用户看到的那三十秒由你决定。

一、周日晚上,AI 按钮变成一句英文报错

苏芮一个人做客服回复助手,39 美元一个月,客户是十几个在电商平台开店的小团队。周日晚八点,正是订单咨询最多的时候,供应商的主接口开始返回 503。

以下情境为教学假设,人物、引语和数字不代表经核实的真实案例。

她的代码只写了「调用、等待、显示」。没有超时,没有重试,也没有第二个供应商。前端转圈三十秒后弹出一句英文报错,用户以为是自己网络问题,反复点击,把还在排队的请求又翻了一倍。

更糟的是草稿。用户已经写了三行回复,点「生成」后页面跳转,回来时输入框空了。那一晚她收到 11 封邮件,其中 4 封要求退款。退款金额不大,但她失去的是「这个东西靠得住」的判断。

她第二天做的第一件事不是换供应商。她先把「失败」当成一个必须设计的状态:接口可能慢、可能拒绝、可能中途断开,产品在每种情况下都要有一条能走完的路。降级不是备用方案,而是功能的一部分;用户真正购买的,是供应商不稳定时仍然能把话说完的确定性。

故障不是小概率。 一个人产品没有 on-call、没有多区域、没有谈判来的 SLA,供应商一次例行发布就可能让功能停摆半小时。把故障当作每月必然发生一次的事件来设计,比赌它不发生更便宜。

停机半小时的代价可以估。 那晚她退了 4 单、收到 11 封邮件、花了两小时回复,直接损失不到 160 美元;但如果那十几个客户里有两家在续费时犹豫,损失就变成每月 78 美元。降级预案买的不是可用性数字,是续费时的信任。

二、第一层:同供应商的超时与重试

第一层不换供应商,只解决「等太久」。三个超时分别管住连接、首 token 和总时长,缺一个都会让请求挂死。

控制项阈值(教学假设)超时后的动作
建立连接3 秒立即取消,进入重试
首 token10 秒中止本次调用,换重试或降级
总时长30 秒停止等待,返回可恢复错误
重试最多 2 次,退避 1 秒、3 秒,带 ±30% 抖动仍失败则进入第二层

三个超时要分开设。 连接 3 秒管的是网络与 DNS,首 token 10 秒管的是供应商排队,总时长 30 秒管的是用户耐心。只设总超时,会出现「连接成功但一直不吐字」的假健康状态;只设连接超时,则慢响应会把并发占满。

阈值要按 p99 取,不按平均值取。 平均 4 秒的接口,p99 可能是 25 秒;按平均值设 10 秒总超时,会把最慢的那批用户全部变成失败。用最近七天的日志取 p95 与 p99,再决定三个数字,别拍脑袋。

重试必须带抖动。 固定间隔会让所有客户端在同一秒再次涌入,把一次抖动放大成雪崩。退避加随机抖动,能把重试摊平到一个区间;两次仍失败就停手,把请求交给下一层,而不是无限重试。

只对可重试的错误重试。 429、500、502、503、504 和连接超时可以重试;400、401、403、422 重试多少次都一样,只会放大账单。把错误码分类写成一张小表,比在 catch 里统一重试更省事。

重试的成本要算进预算。 一次用户请求最多变成三次计费调用,第 02 篇的每用户成本必须乘上这个系数。若重试率长期高于 5%,说明供应商的尾延迟已经不适合当前场景,该考虑换层而不是继续加退避。

不要把重试藏起来。 如果用户已经等了 20 秒,界面要显示「正在换一条线路」,而不是继续转圈。透明不会让等待变短,但会让用户知道产品还在工作。

三、第二层:第二供应商与弱模型

第二层的目标不是「效果一样好」,而是「还能给出一个可用的结果」。它必须在平时就接好,故障当天才找备用,等于没有备用。

触发条件降级目标质量代价用户感知
主供应商 5xx 或连续 3 次超时第二供应商的同档模型措辞差异,需重跑评测多等 2 到 5 秒
第二供应商也失败弱模型完整性下降,需要标注「简版」结果更短
弱模型仍失败或触发成本熔断模板或缓存只给固定结构,不生成新内容明确标注「模板回复」
三层都不可用人工队列延迟以小时计进入待处理列表

第二供应商要平时就跑。 每周用同一组 50 条用例在两家各跑一次,记录通过率、p95 延迟和单条成本。只写在配置里、从没跑过的备用供应商,故障时大概率因为鉴权、模型名或参数差异直接失败。

提示与解析必须保持中立。 不要把某家的特殊参数、特殊字段或特殊格式写进业务代码;用一层薄适配把请求和响应归一化。这样换供应商是改配置,不是改二十处解析逻辑。

弱模型不是随便挑一个便宜的就上。 它要满足两个条件:能在 30 秒内返回,且在你的 50 条用例上不出现严重错误。完整性可以下降,事实性和安全性不能下降;否则降级只是在制造另一种事故。

模板与缓存要覆盖最高频的五个场景。 退款安抚、物流查询、缺货说明、改地址、发票问题,每个写一段可填空的固定话术;同一个问题在 24 小时内重复出现时,直接返回上次已确认的答案并标注来源。模板不智能,但它能在所有模型都不可用时让用户把话发出去。

降级不能静默。 用户需要知道这封回复是「简版」还是「模板」,也需要一个「重新生成」的入口。静默降级会让用户在不知情的情况下把低质量内容发给自己的客户,那比报错更伤信任。

备用层也要有预算。 第二供应商按同样的单价计费,故障期间流量翻倍,账单也会翻倍。给降级路径单独设日预算,超过就提前进模板,而不是让备用层变成第二个成本黑洞。

四、第三层:熔断、队列与用户可见行为

第三层管的是「别再打了」。当供应商已经明确不可用,继续请求只会拉高延迟、烧掉预算,并让恢复后的第一波流量更难处理。

熔断状态判定系统动作用户看到
关闭正常放行主供应商正常生成
打开60 秒内 5 次失败直接走降级,不再请求主供应商稍慢,但不再空转
半开打开后 30 秒只放 1 个探针请求无感
队列满待处理超过 50 条或等待超过 15 分钟丢弃低优先级功能,保留核心排队提示与预计时间

熔断参数要敢于写死。 60 秒内 5 次失败就打开,30 秒后半开放一个探针,探针成功再关闭。参数不需要调得很精细,关键是有明确的状态机,而不是每个请求都去试一次。

429 要尊重 Retry-After。 供应商明确告诉你多久后再来,就不要按自己的退避硬闯。把 Retry-After 换算成队列的等待时间,超时未恢复就走降级;无视这个头,只会换来更长的封禁。

队列一定要有上限。 无上限的队列会把内存和用户耐心一起耗尽。设 50 条或 15 分钟的上限,满了先丢批量、导出、润色这类低优先级功能,保留用户正在等待的那一条。

用户可见行为要写死五条。 核心工作流不依赖 AI 也能完成;AI 按钮禁用时说明原因与预计恢复时间;草稿自动保存并在恢复后回填;失败页提供重试与人工入口;状态页与产品内提示使用同一句话。

状态页不需要复杂。 一个静态页面加三个状态:正常、降级、故障,写清受影响的功能和更新时间。它的作用不是展示技术,而是让用户不必发邮件问「是不是你们坏了」。

同一句提示要复用。 按钮禁用文案、失败页、状态页、邮件通知使用同一句「AI 生成暂时不可用,预计 XX:XX 恢复,你仍可手动编辑」,避免用户在四个地方看到四种说法。

每月做一次 30 分钟故障演练。 在测试环境注入 timeout、429、500 三种响应,每种跑 20 个请求,记录降级成功率、用户可见失败率和补偿成本。演练不需要真实故障,只需要确认每条路径都还能走通。

演练结果要进复盘表。 哪一层最先触发、哪一层没有生效、用户看到了什么、补了多少钱,四项都写下来。连续两个月同一层失效,说明问题在实现而不是供应商,应该改代码而不是换合同。

五、行动清单与复算验收

先做三件今晚就能上线的事:给请求加三个超时、把重试限制在可重试错误、给 AI 按钮加一个能说明原因的失败态。它们不需要第二家供应商,却能消掉大部分「转圈三十秒然后英文报错」的体验。

然后再接第二层与第三层。第二层至少提前两周准备,因为要跑评测、要适配响应格式;第三层可以先用静态模板和人工邮箱兜底,等量上来再补队列。

  • 为连接、首 token、总时长分别设置 3 秒、10 秒、30 秒超时。
  • 只对 429、5xx 与连接超时重试,最多两次并加抖动。
  • 接一家第二供应商,用同一组 50 条用例每周双跑。
  • 准备弱模型与五个高频场景的模板话术,标注「简版」或「模板」。
  • 配置 60 秒 5 次失败的熔断与 30 秒半开探针。
  • 设置队列上限,写清满了以后丢弃哪些低优先级功能。
  • 让 AI 失败页保留草稿,并提供重试、人工入口与状态页链接。
  • 每月注入 timeout、429、500 各 20 次,记录三个指标与补偿成本。

验收标准:在供应商完全不可用的 30 分钟内,用户仍能完成核心工作流、看到一句能读懂的原因,并且你能从日志里算出降级成功率和这次故障的补偿成本。

可用性 = 1 − 失败请求 ÷ 总请求 = 1 − 46 ÷ 2000 = 97.7%
降级成功率 = 成功降级请求 ÷ 触发降级请求 = 168 ÷ 180 = 93.3%
三层覆盖率 = 任一层成功请求 ÷ 总请求 = 1954 ÷ 2000 = 97.7%
结论:覆盖率与可用性同值,说明 46 次失败全部落在三层之外;先把失败归类,再决定补第四层还是收窄入口

使用边界与实操验收

本文假设 AI 功能已经上线,且你至少能改自己的超时、重试和前端状态。它不讨论网关实现、跨区域容灾与供应商合同条款;这些超出一个人当前能维护的范围。

实操验收建议挑一个低峰时段做一次真实演练:把主供应商的密钥临时改错,观察产品是否在 60 秒内进入降级、用户是否看到可读提示、草稿是否还在、恢复后是否能继续。整个过程控制在 30 分钟内,结束后把三个指标填进同一张表。

三种情形不适用本文。 一是 AI 是产品唯一价值、没有非 AI 路径可保留;二是企业私有部署,故障沟通由客户管理员负责;三是供应商合同承诺了赔付,降级策略需要与法务口径一致。

关键参考与核验范围

核对日期:2026-10-25。下列来源仅支持明确标注的机制或原则。

使用边界。 三层预案、2000 次请求与成功率是教学假设,不是供应商 SLA。备用模型与主模型可能同时计费,不能假设超时就未计费。

如何自行复核。 在总截止时间内模拟超时、429、503与备用失败,检查实际返回、预算消耗和用户提示;缓存必须按租户、权限及有效期隔离。

系列导航

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页

「Indie」更多文章

  1. 开源项目验收:十项能力、四维评分与三种不该开源的项目
  2. 治理、fork 与退出:17 位贡献者、82% 的提交与一次改协议的代价
  3. 双许可与企业版:九家询价、两家成交与 4,800 美元