接口一直返回 429,但错误体里的 code 写的是 insufficient_quota,而不是常见的 rate_limit_exceeded。两个都是 429,含义却完全不同,按限流去加重试只会白等。

先看响应体里的 code 字段

r = requests.post(url, headers=h, json=body)
if r.status_code == 429:
    print(r.json()["error"]["code"])

rate_limit_exceeded 表示单位时间的请求数或 token 太多,退避重试有用;insufficient_quota 表示账户额度已经用完,重试多少次都不会成功。

额度用完的几种常见情况

  • 赠送额度带有效期,到期后直接归零
  • 绑定的卡扣款失败,账户进入欠费状态
  • 密钥属于某个项目,项目级额度单独计算并已耗尽

登录控制台的用量页面看当前计费周期已用金额,再确认这把密钥归属的组织与项目,两边对不上就是拿错了密钥。

重试策略要按错误码分流

for i in range(5):
    r = requests.post(url, headers=h, json=body)
    if r.status_code != 429:
        break
    if "insufficient_quota" in r.text:
        raise RuntimeError("额度不足,停止重试")
    time.sleep(2 ** i)

对限流做指数退避、对额度错误直接失败并告警,比统一无脑重试省时间。监控里把这两种 429 分开统计,也能避免把额度问题误判成流量高峰。

确认额度到底还剩多少

控制台的用量页面能看到计费周期内的消耗曲线,曲线在某一刻断掉、之后全是报错,基本就是额度耗尽。再检查账户是否有多把密钥、是否分属不同项目,很容易出现主账号有额度、业务用的子项目密钥却没额度的情况。

把密钥和项目对应关系写进配置注释,换人维护时不必再靠猜。

作者 9823189

发表回复