外观
模型网关超时重试与级联故障复盘
30 秒复盘结论: 这是一场故障演练:上游没有传递全链路截止时间,模型网关和客户端分别进行同步重试,供应商超时后一次业务请求被放大为多次模型调用,最终造成队列堆积、延迟上升和成本失控。止损是限流、熔断、停止重试并降级到受控模型;长期修复是统一 Deadline、重试预算、抖动退避、负载丢弃和容量感知路由。当前没有真实流量、费用或可用性损失数据。
目录
1. 摘要与小白解释
像一条客服热线:电话接不通时,用户、前台和转接员都同时重拨。原本一位用户变成十几通电话,线路更拥堵,真正能接通的概率反而下降。技术上,用户、模型网关和供应商 SDK 分别对应多层重试者;热线占用对应连接、并发槽位和队列;“最多等多久”对应全链路 Deadline。
类比没有覆盖流式响应已返回部分 Token、供应商计费、请求可取消性和不同模型质量边界。生产系统必须判断剩余时间是否足够完成下一次尝试,而不是只限制重试次数。
| 项目 | 内容 |
|---|---|
| 现象 | 队列增长、P99 延迟上升、超时率和调用成本同时恶化 |
| 直接原因 | 多层同步重试放大请求 |
| 根本原因 | 没有统一时间预算、容量预算与重试所有权 |
| 止损 | 入口限流、供应商熔断、停止重试、降级或拒绝 |
| 修复 | Deadline 传播、重试预算、Jitter、负载丢弃、容量路由 |
2. 故障教学图片
图:故障教学图片|模型网关重试放大与级联恢复
替代文本: 客户端、模型网关、请求队列和两个供应商之间的同步重试放大流量,形成队列、延迟和成本故障;限流、熔断、停止重试与全链路预算恢复,事实边界为故障演练。
教学图片待人工审图客户端、模型网关、请求队列和两个供应商之间的同步重试放大流量,形成队列、延迟和成本故障;限流、熔断、停止重试与全链路预算恢复,事实边界为故障演练 暂不公开,正文与 Mermaid 图可正常阅读。
读图结论: 重试是受预算约束的恢复手段;没有总超时和容量预算时,它会成为故障放大器。
红色虚线表示重复流量回流,绿色区域先切断放大回路,再用 Deadline 和重试预算恢复。图中的供应商名称是演练占位,不指向真实厂商。
图片生成记录: model=gpt-image-2,generated=2026-07-15,prompt_version=v1;查看 Prompt。PNG C2PA 记录 softwareAgent=gpt-image、version=2.0。
质检状态: Agent 已核对中文、箭头与事实边界;维护者审图待完成。
3. 证据、影响与指标
| 结论 | 类型 | 证据或验证动作 |
|---|---|---|
| 多层重试可放大请求 | 工程机制 | Trace 统计单个 request_id 的总 attempt 数 |
| 供应商变慢是根因 | 待验证 | 需要区分供应商延迟与本地排队时间 |
| 立即切换备用供应商总能恢复 | 不成立 | 备用容量不足时会传播故障 |
| 本文是线上事故 | 不成立 | 没有真实告警、账单或版本记录 |
合成 Trace 字段:request_id、deadline_ms、remaining_budget_ms、attempt、retry_owner、provider、queue_wait_ms、provider_latency_ms、cancelled、fallback_reason。
text
retry_amplification = 实际模型调用 attempt 总数 / 入口业务请求数
deadline_exhaustion_rate = 到达网关时剩余预算不足的请求数 / 入口请求数
queue_wait_ratio = 排队耗时 / 端到端耗时指标按租户、模型、供应商、流式/非流式和请求类型分桶;本文不预填阈值。
相对时间线:T0 注入供应商延迟;T0+1 客户端和网关同时重试;T0+2 队列增长;T0+3 限流熔断并停止重试;T0+4 修复后按灰度流量恢复。
4. 技术栈与架构
4.1 技术点清单
| 技术点 ID | 技术点/环节 | 类型 | 采用方案 | 链路职责 | 版本/证据边界 |
|---|---|---|---|---|---|
| TP-01 | 时间预算 | 协议 | 单调递减 Deadline | 限制全链路最大时间 | 演练协议 |
| TP-02 | 重试控制 | 中间件 | 预算加指数退避和 Jitter | 限制放大与同步风暴 | 待压测 |
| TP-03 | 故障隔离 | 服务治理 | 熔断、并发隔离、负载丢弃 | 保护网关和备用供应商 | 待演练 |
| TP-04 | 降级路由 | 服务 | 容量感知的模型/供应商降级 | 在质量、时间和成本间取舍 | 需业务基准集 |
图:架构|模型网关的时间、容量与供应商隔离边界
替代文本: 客户端经过入口限流进入模型网关,网关读取 Deadline 和重试预算,通过隔离舱调用主备供应商;队列、熔断器和容量指标共同控制路由与降级。
图表加载中…
读图结论: 主备供应商必须拥有独立并发和熔断边界,切换路由不能共享同一个无限队列。
5. 调用流程
图:技术调用流程|预算耗尽、停止重试与降级恢复
替代文本: 客户端携带 Deadline 调用网关;网关扣除排队时间并调用供应商,超时后检查剩余时间、重试预算和备用容量,不满足条件就快速失败或降级,满足条件才抖动重试。
图表加载中…
读图结论: 是否重试由剩余时间、预算和实时容量共同决定,而不是由“错误可重试”单独决定。
6. 止损、根因与选型
止损顺序:冻结配置发布;入口按优先级限流;关闭网关内部重试;熔断异常供应商;为关键请求保留隔离容量;可接受时降级小模型;无安全路径时明确失败,禁止无限排队。
- 直接原因: 客户端、网关和 SDK 重复拥有重试权。
- 根本原因: 未定义全链路 Deadline、重试预算和单一重试所有者。
- 促成因素: 无界队列、主备共享连接池、缺少取消传播、按成功率而非剩余容量路由。
- 非原因: 单纯提高超时时间不会消除请求放大。
- 防线失效: 压测没有注入慢响应、限流和主备同时降容。
| 技术点 ID | 候选方案 | 优点 | 缺点/代价 | 适用场景 | 不适用场景 | 选择结论与依据 |
|---|---|---|---|---|---|---|
| TP-01 | 每层独立 Timeout | 接入简单 | 预算可叠加超出用户 SLA | 单层调用 | 多级网关 | 不采用 |
| TP-01 | 端到端 Deadline | 语义一致、可取消 | 需要全链路传递 | 多级调用 | 不支持取消的遗留依赖 | 采用 |
| TP-02 | 固定次数立即重试 | 简单 | 同步放大 | 极少量瞬时错误 | 容量故障 | 不采用 |
| TP-02 | 预算 + 退避 + Jitter | 控制放大 | 参数需压测 | 生产网关 | 无幂等副作用调用 | 采用 |
| TP-03 | 无限排队 | 表面不丢请求 | 延迟和内存失控 | 无 | 在线推理 | 禁止 |
| TP-03 | 有界队列 + 负载丢弃 | 保护系统 | 会显式拒绝 | 有优先级在线服务 | 不能接受任何拒绝且有离线缓冲 | 采用 |
| TP-04 | 盲切备用供应商 | 实现快 | 可能击穿备用 | 备用容量已预留 | 备用状态未知 | 不采用 |
| TP-04 | 容量与质量感知降级 | 风险可控 | 需要基准和实时指标 | 多模型路由 | 强一致模型要求 | 条件采用 |
7. 验证、防复发与面试表达
验证矩阵覆盖:供应商慢响应、429、连接断开、流式中断、主备同时降容、客户端取消、Deadline 已耗尽、重试风暴和降级模型质量门槛。验收证据必须包含单请求 attempt 上限、队列边界、取消传播、无孤儿请求和成本分桶。
防复发:统一网关 SDK;禁止业务层私自重试;Trace 记录 retry_owner;配置变更进行影子压测;熔断与降级 Runbook 明确恢复水位;按供应商和模型设置独立隔离舱;账单异常与请求放大联合告警。
难点卡: 最难的是在延迟、可用性、质量和成本约束下判断“是否还有资格重试”,而不是实现重试循环。
反模式: 超时就同时请求所有供应商;只看成功率不看队列等待;把备用供应商当无限容量;增加 Timeout 掩盖排队。
7.1 30 秒面试回答
这是一次模型网关故障演练:供应商变慢后,客户端和网关多层同步重试,把一次请求放大为多次调用并造成队列和成本级联。我先限流、熔断并停止重试,根因是没有端到端 Deadline、重试预算和单一重试所有者。长期修复通过有界队列、抖动退避、容量感知降级和故障注入验证;当前没有真实生产指标。
7.2 60~90 秒与追问
排查时先分离入口耗时、排队耗时和供应商耗时,再按 request_id 统计 attempt 与 retry_owner,避免把本地排队误判成供应商慢。重试条件必须同时满足剩余 Deadline、重试预算、幂等安全和备用容量;否则快速失败或降级。方案代价是会显式拒绝一部分低优先级请求,但能保护关键流量和总体恢复。
追问:流式响应中断能否重试?如何取消已经发出的备用请求?Deadline 如何跨协议传递?降级模型质量怎样验收?为什么 Hedging 也会放大流量?
8. 总结
一句话记忆: 重试只有在时间、幂等和容量预算内才是恢复手段。
- 分离排队、网关与供应商耗时;
- 统一 Deadline 和重试所有权;
- 用有界队列、隔离舱和熔断切断级联;
- 降级必须同时验证容量、质量与成本;
- 本文是故障演练,不是实际事故复盘。