限流与重试
两层限流
我们的限流分两层,作用点不一样:
| 层级 | 作用对象 | 说明 |
|---|---|---|
| 平台级 | 整个 /api/* 管理接口 | 保护控制台不被刷。已调到很高,正常使用不会碰到 |
| 令牌级 | 单个 API 令牌 | 你可以在控制台给令牌设 RPM(每分钟请求数)和额度上限 |
你会碰到的通常是令牌级
如果自己调 API 报 429,先看是不是给那个令牌设了太低的速率限制。
429 长什么样
json
{
"error": {
"message": "当前分组上游负载已饱和,请稍后再试",
"type": "new_api_error",
"code": "rate_limit_exceeded"
}
}按 Retry-After 响应头等,或者指数退避重试。
客户端该怎么做
指数退避重试
python
import time
import random
from openai import OpenAI, RateLimitError, APIStatusError
client = OpenAI(
api_key="sk-你的密钥",
base_url="https://api.blueworkshop.top/v1",
)
def chat_with_retry(messages, model="deepseek-v4-pro-0813", max_retries=4):
for attempt in range(max_retries):
try:
return client.chat.completions.create(model=model, messages=messages)
except RateLimitError:
if attempt == max_retries - 1:
raise
wait = min(2 ** attempt + random.random(), 30)
time.sleep(wait)
except APIStatusError as e:
# 5xx 也值得重试,4xx 重试没意义
if e.status_code < 500 or attempt == max_retries - 1:
raise
time.sleep(min(2 ** attempt, 30))服务端也会重试
网关对上游失败有自动重试,最多 3 次,命中这些状态码才重试:
100-199, 300-399, 401-407, 409-499, 500-503, 505-523, 525-599注意两个故意不重试的码:
| 状态码 | 为什么不重试 |
|---|---|
504 | 网关超时,重试大概率还是超时 |
524 | 上游卡住超过 120 秒被 Cloudflare 掐断,再等一轮没意义 |
双层重试要算总时长
服务端重试 3 次 × 客户端重试 4 次 = 最坏 12 次请求。对你的用户来说就是「一直转圈」。
建议:客户端重试 2 次就够,把超时设短一点(比如 60 秒),早点失败早点给用户反馈。
并发控制
如果你的场景是批量调用,别一次甩几千个并发请求:
python
from concurrent.futures import ThreadPoolExecutor
# 控制在 5-10 并发,比自己开 100 个线程稳得多
with ThreadPoolExecutor(max_workers=8) as pool:
results = list(pool.map(call_api, items))并发不是越高越好
上游有自己的并发上限,你开再多的线程也只是在本地排队,还会因为超时白白浪费额度。
超时设置
| 场景 | 建议超时 |
|---|---|
| 短问答(< 200 token) | 30 秒 |
| 长回答、写代码 | 120 秒 |
| 流式输出 | 连接 30 秒,读超时 300 秒 |
| 推理模型(o 系列 / R1) | 300 秒以上,它们真的会想很久 |
python
client = OpenAI(
api_key="sk-你的密钥",
base_url="https://api.blueworkshop.top/v1",
timeout=120.0, # 别用默认值,太短
max_retries=2, # SDK 自带重试,别和手动重试重复叠加
)出问题怎么定位
| 现象 | 大概率原因 |
|---|---|
| 偶发 429 | 上游瞬时负载,退避重试即可 |
| 持续 429 | 令牌设的速率太低,去控制台调高 |
| 429 但用量很低 | 上游厂商对这个模型整体限流,换模型试 |
| 502 / 530 | 上游服务抖动,等几分钟;持续超过 10 分钟联系我们 |
| 524 | 上游超时,通常是提示词太长或模型太慢,缩短输入试试 |