Claude Status监控:Claude API 频繁返回 529 `overloaded_error`?一份生产环境排障 Playbook

利益相关:下面所有结论来自我在生产环境长期调用 Claude API 的观察,数据基于公开接口。文末会提到一个我日常在用的社区状态面板(非官方,与 Anthropic 无从属关系),仅作为一个排障信号源。

先上结论,给凌晨被 PagerDuty 叫醒的同行省一个小时。

结论先行

  • HTTP 529 overloaded_error 不是你的限流。它是 Anthropic 告诉你:你请求的那个模型,整个容量池已经打满。
  • 同模型、同区域、同请求、同一秒内硬重试,正是把墙撞得更厚的方式。你的重试风暴就是 529 想阻止的东西。
  • 尊重 retry-after。没这个头就加 2--8 秒抖动,非关键路径立即降级到 Haiku。
  • 当你自己的重试策略让情况变糟时,去看第三方信号(社区状态面板、跨区域延迟探针、用户上报),不要一上来就升级到团队群里。

529 和 429 不是一回事

我见过的大部分 Claude 客户端封装,只对 429 做了重试逻辑,到此为止。对你的 API key 配额而言这没问题。但 Claude 还会返回:

json 复制代码
{
  "type": "error",
  "error": {
    "type": "overloaded_error",
    "message": "Overloaded"
  }
}

HTTP 状态码是 529

  • 429 = 发太多了
  • 529 = 模型容量池 太小了

同一个请求,下一秒重放,得到的还是同一个响应。两种失败模式需要的重试策略完全不同。

先看响应头

碰到 529 / 429,第一件事不是改代码,是看响应头里有没有这几个:

yaml 复制代码
anthropic-ratelimit-requests-limit: 4000
anthropic-ratelimit-requests-remaining: 3987
anthropic-ratelimit-requests-reset: 2025-11-03T12:34:56Z
anthropic-ratelimit-tokens-limit: 400000
anthropic-ratelimit-tokens-remaining: 398420
anthropic-ratelimit-tokens-reset: 2025-11-03T12:34:00Z
retry-after: 12

判断逻辑:

  • requests-remaining / tokens-remaining 还够 → 是服务端容量墙,不是你的 key 问题,不要改你的 gateway 配置
  • retry-after 有值 → 严格按值等待,最常见错误是客户端库忽略这个头 500ms 后硬重试

一个真正尊重 529 的重试策略

TypeScript,不依赖 SDK,生产用的是这个:

ts 复制代码
type RetryInput = { attempt: number; retryAfterSec?: number };

function backoff({ attempt, retryAfterSec }: RetryInput): number {
  if (retryAfterSec) return retryAfterSec * 1000;
  // 1s, 2s, 4s, 8s, 16s --- 叠加 50% jitter
  const base = Math.min(16_000, 1_000 * 2 ** attempt);
  return Math.floor(base * (0.5 + Math.random() * 0.5));
}

async function callClaude(req: ClaudeRequest, maxAttempts = 5) {
  for (let attempt = 0; attempt < maxAttempts; attempt++) {
    const res = await fetch("https://api.anthropic.com/v1/messages", {
      method: "POST",
      headers: {
        "x-api-key": process.env.ANTHROPIC_API_KEY!,
        "anthropic-version": "2023-06-01",
        "content-type": "application/json",
      },
      body: JSON.stringify(req),
    });

    if (res.ok) return res.json();

    if (res.status === 529 || res.status === 429) {
      const retryAfter = Number(res.headers.get("retry-after")) || undefined;
      if (attempt === maxAttempts - 1) throw new Error(`claude ${res.status} after ${maxAttempts}`);
      await new Promise(r => setTimeout(r, backoff({ attempt, retryAfterSec: retryAfter })));
      continue;
    }
    throw new Error(`claude ${res.status}: ${await res.text()}`);
  }
  throw new Error("unreachable");
}

两个关键点:

  1. 抖动(jitter)必须加。十个 worker 用确定性的退避时间,会在队列刚开一条缝的那一瞬间集体冲进去,把墙再撞一次。随机抖动把负载摊开。
  2. 最大退避封顶。别让第 7 次尝试 sleep 128 秒,那不叫重试,叫把用户请求吊死。16 秒还不行,就走 fallback,不是继续等。

模型降级作为一等公民

不是需要深度推理的路径,我第二次 529 就立刻降到 Haiku:

ts 复制代码
async function callWithFallback(req: ClaudeRequest) {
  try {
    return await callClaude(req, 2); // 主模型快速失败
  } catch {
    const downgraded = { ...req, model: "claude-haiku-4-5-20251001" };
    return callClaude(downgraded, 3);
  }
}

Haiku 是独立的容量池。Opus / Sonnet 打满的时候,Haiku 往往正常。这是质量换可用性的交换,在短时容量波动面前几乎永远是对的选择。

不要完全相信你自己的重试

真正的坑:一旦你有了重试策略,529 就从你的监控里消失了。p99 悄悄爬升,latency budget 悄悄被吃掉,面板全绿,用户却在骂你。

我依赖两个信号来看见这种"隐性 529 滴漏":

  1. 按模型拆开的错误计数器 :anthropic_http_5xx_total{model="opus",code="529"} 必须作为独立指标,不要合并到 api_errors_total。529 要像账单一样显眼。
  2. 跨区域延迟探针 :判断自己代码有 bug 之前,先确认 Claude 是不是 全球 都在慢,而不仅是你这个区域。

第二点我自己用的是一个社区面板 ------ claudestatus.com,非官方,与 Anthropic 无任何从属 。某次凌晨值班我在 Reddit 翻到的,后来一直开着用:它通过 Anthropic Statuspage 公共 API 抓状态,同时从 17 个国家跑 HTTP 延迟探针,再叠加社区上报。生产告警响起来时,我会先看一眼上面的 30 天历史曲线 确认是不是全局事件,十有八九是一波区域或模型级容量波动,等几分钟自己过,不用叫醒同事。

下一次 529 的 checklist

告警响起时,按这个顺序:

  1. 看响应头 ------ requests-remaining 是不是 0?不是 0 那就是容量墙,改 gateway 没用
  2. retry-after ------ 有就严格用,别自作聪明
  3. tokens-remaining ------ 长 prompt 会先打爆 token 桶而不是请求桶
  4. 看外部信号 ------ 只是你,还是你的区域,还是全球?社区面板 10 秒内回答
  5. 降级 / fallback ------ 切 Haiku、走缓存、告诉用户稍等一分钟
  6. 最后 才去怀疑自己的代码

没什么高深的,我踩的最大坑就是把 529 当 429,抱着一堵墙硬重试。


上面提到的面板:claudestatus.com,社区维护,非官方,与 Anthropic 无任何从属

相关推荐
兔老霸夏17 小时前
claude_agent_sdk 功能简介
架构·claude
潘锦18 小时前
OpenClaw 的 Skills 的实现和 Claude Code 不一样
agent·claude
钱多多_qdd18 小时前
claude code(四):【Claude Code官方最佳实践2️⃣】:为claude提供更多工具
ai·claude
与虾牵手19 小时前
Claude Code 怎么配置自定义 API 地址?2026 最完整的 3 种方案实测
ai编程·claude
星浩AI1 天前
你和 10 倍生产力之间,差的就是它 : claude-howto,用一个周末掌握ClaudeCode
github·claude·vibecoding
小凡同志1 天前
OpenSpec 手把手实战:从零跑通一个完整功能
前端·ai编程·claude
敲上瘾1 天前
大模型接入从入门到实战:API/SDK/本地部署/Claude Code 路由全解析
人工智能·深度学习·机器学习·json·aigc·claude
Bigger1 天前
第六章:我是如何剖析 Claude Code 的终端界面渲染原理的
前端·react.js·claude
李昊哲小课1 天前
deepin25.10安装claude
claude·claude code·claude-code·cc-switch