当 Claude API 在高并发下开始返回 429,很多系统不是“慢一点”,而是直接雪崩:队列堆积、重试风暴、上游超时、下游告警连锁。
这篇给你一套可落地的生产方案:自适应并发 + 指数退避抖动 + 配额隔离。目标不是“永不 429”,而是把 429 控制在可恢复区间,并维持服务 SLO。
先定目标:别追求零错误,追求稳定恢复
建议先定 3 个可观测目标:
- 429 比例:
< 2%(5 分钟滑窗) - P95 总延迟:
< 8s(含排队) - 重试放大量:
< 1.3x(每个原始请求平均总尝试次数)
只要这 3 个指标稳住,业务层通常不会感知“灾难级抖动”。
一、把并发阀门从“写死”改成“自适应”
为什么固定并发会害死人
固定并发(比如永远 64)在流量高峰和模型配额波动时,容易出现“过载后还在猛踩油门”。
实现思路(AIMD)
- 成功窗口内小步增加并发(Additive Increase)
- 触发 429/5xx 时快速减小并发(Multiplicative Decrease)
伪代码:
type Gate struct {
max int64 // atomic
}
func (g *Gate) OnHealthyWindow() {
cur := atomic.LoadInt64(&g.max)
atomic.StoreInt64(&g.max, min(cur+1, 128))
}
func (g *Gate) OnThrottle() {
cur := atomic.LoadInt64(&g.max)
next := int64(float64(cur) * 0.7)
if next < 4 { next = 4 }
atomic.StoreInt64(&g.max, next)
}
生产建议:
- 上限别超过你实测稳定吞吐的
1.2x - 下限至少保留
4~8,避免完全“饿死” - 每 30s~60s 才允许加一次,避免抖动
二、重试必须“有脑子”:指数退避 + 全抖动
429 后立刻重试是最常见事故放大器。
正确姿势
- 首次重试基线:
200~400ms - 退避:
base * 2^attempt - 抖动:
rand(0, backoff)(Full Jitter) - 最大重试:在线请求建议
2~3次
Go 示例:
func backoff(attempt int, base, capMs int) time.Duration {
max := base * (1 << attempt)
if max > capMs { max = capMs }
return time.Duration(rand.Intn(max+1)) * time.Millisecond
}
关键:重试预算要和请求超时预算联动。总预算 8 秒,就别让第 3 次重试在第 9 秒才发出去。
三、配额隔离:别让一个租户拖垮全局
如果你做多租户,最危险的是“共享一锅并发和令牌”。
最低可用隔离
- 全局池:保护上游配额
- 租户池:限制单租户爆发
- 优先级池:交互请求 > 批处理请求
一个简单配比:
- 全局并发 60
- 关键租户保底 20
- 普通租户共享 40
- 批处理最多吃 15(且可被抢占)
这样即便批处理任务打满,也不会把在线流量一起带走。
四、熔断 + 半开恢复:阻止重试风暴二次伤害
在 429/5xx 连续高于阈值时,短路一段时间:
- Open 条件:最近 30s 错误率 > 25%
- Open 时长:10~20s
- Half-open:只放 5~10% 探针流量
- 探针恢复成功再逐步放量
配合“降级响应”(如返回缓存摘要、延迟提示)比一股脑超时好太多。
五、观测面板:没有这几张图,你是在盲飞
至少补齐:
requests_total{model,status}retry_attempts_histogramqueue_wait_ms_p95inflight_by_tenantcircuit_breaker_state
排障顺序:
- 先看 429 是否集中在某模型/某租户
- 再看队列等待是否先抬升
- 最后看重试放大量是否失控
六、可直接落地的“止血配置”
适合先救火:
llm_gateway:
timeout_ms: 8000
max_inflight_global: 48
max_inflight_per_tenant: 12
retry:
max_attempts: 3
base_backoff_ms: 250
cap_backoff_ms: 2500
jitter: full
circuit_breaker:
error_rate_threshold: 0.25
open_seconds: 15
half_open_probe_ratio: 0.1
先用这套把系统拉回稳态,再按真实流量做细化调参。
常见误区
- 误区 1:把 429 当网络抖动处理 → 结果是无限重试
- 误区 2:所有请求同优先级 → 关键链路被批任务淹没
- 误区 3:只有全局限流没有租户隔离 → 大客户把小客户全拖死
总结
Claude API 的 429 不可怕,可怕的是没有“系统级节流策略”。
用这 3 件事就能显著降风险:
- 自适应并发(动态阀门)
- 指数退避 + 全抖动(抑制重试风暴)
- 配额隔离 + 熔断恢复(保护关键流量)
先把系统做成“可退化、可恢复、可观测”,再追求峰值吞吐。稳定赚钱,比偶尔跑得快更重要。