Guides

限流与重试

账户、密钥和上游维度的限流策略,以及 429 的处理方式。

概述

限流用于保护账户预算、共享上游容量和整体服务稳定性。

UOUODUO Gateway 可能在账户、项目、API key、模型和上游供应商多个维度限流。

应用侧必须把 429 当作正常可恢复状态处理。

常见限流维度

维度说明典型影响
RPM每分钟请求数高频小请求
TPM每分钟 token 数长 prompt 或长输出
并发数同时运行的请求数量流式请求或任务请求
预算项目或账户预算触顶费用保护
上游容量某个供应商短期拥塞单一模型不可用

限流值可能按账户等级、团队策略和模型能力不同而变化。

429 响应

典型响应:

{
  "error": {
    "message": "Rate limit exceeded. Please retry later.",
    "type": "rate_limit_error",
    "code": "rate_limit_exceeded"
  }
}

如果响应头包含 `Retry-After`,客户端应等待指定秒数后重试。

没有 `Retry-After` 时,使用指数退避。

指数退避

推荐策略:

  1. 第一次失败等待 500ms 到 1s。
  2. 每次失败后等待时间翻倍。
  3. 加入 0 到 250ms 的随机抖动。
  4. 最大等待时间控制在 30s 以内。
  5. 总重试次数控制在 3 到 5 次。

Node.js 示例:

function sleep(ms: number) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

function retryDelay(attempt: number) {
  const base = Math.min(30_000, 500 * 2 ** attempt);
  return base + Math.floor(Math.random() * 250);
}

什么时候不要重试

不是所有错误都适合重试。

不要自动重试以下情况:

  • 401 或 403,说明认证或权限错误
  • 400 或 422,说明请求参数错误
  • 余额不足或预算触顶
  • 用户主动取消的请求

可以重试以下情况:

  • 429 限流
  • 502 上游异常
  • 503 临时不可用
  • 504 超时
  • 网络连接被重置

控制并发

对于批量任务,不要一次性把所有请求打满。

建议使用队列:

const concurrency = 4;

先从较小并发开始,观察 `/app/usage` 和 `/app/logs`。

如果主要是 TPM 触顶,降低并发不一定够,还需要缩短输入或输出。

降低 token 压力

常见优化:

  • 删除重复 system prompt
  • 压缩历史消息
  • 降低 `max_tokens`
  • 对长文档先摘要再提问
  • 对批量分类任务使用更小模型

token 限流通常比请求数限流更容易被忽略。

UI 提示

面向用户的产品建议显示可恢复提示:

“当前请求过多,系统将在几秒后重试。”

不要把 429 显示成“系统崩溃”。

后台任务可以进入排队状态,并显示下次重试时间。

申请更高配额

当你的生产流量稳定触顶,请准备以下信息:

  • 账户或团队名称
  • 使用场景
  • 目标模型
  • 预期 RPM 和 TPM
  • 峰值时间段
  • 是否需要并发流式响应

这些信息能帮助更快判断应该提升账户限额、项目限额还是上游容量。

监控建议

至少监控以下指标:

  • 429 数量和占比
  • 平均重试次数
  • 最终失败率
  • 每模型 RPM 和 TPM
  • 成功请求延迟

把限流和预算触顶分开统计,排障会更清晰。