429 Rate Limit
429 Too Many Requests 表示请求频率或并发量超出了限制。服务器通过此状态码告知客户端需要降低请求速率。
错误示例
{ "error": { "message": "Rate limit exceeded", "type": "rate_limit_error", "code": "rate_limit_exceeded" }}原因分析
| 原因 | 说明 |
|---|---|
| 请求频率过高 | 短时间内发送了过多请求,超出 RPM(每分钟请求数)限制 |
| 并发限制 | 同时进行的请求数量超出并发上限 |
| 额度限制 | Key 的使用额度已耗尽 |
| Token 限制 | 单次请求的 token 数量超出限制 |
排查步骤
1. 查看响应头中的限流信息
服务器通常在响应头中返回限流相关信息:
curl -i "$BASE_URL/v1/chat/completions" \ -H "Authorization: Bearer $API_KEY" \ -H "Content-Type: application/json" \ -d '{"model": "gpt-4o", "messages": [{"role": "user", "content": "Hello"}]}'关注以下响应头:
| 响应头 | 说明 |
|---|---|
X-RateLimit-Limit | 当前限制的最大请求数 |
X-RateLimit-Remaining | 剩余可用请求数 |
X-RateLimit-Reset | 限制重置时间(Unix 时间戳) |
Retry-After | 建议等待的秒数后重试 |
2. 检查请求频率
统计你的应用在短时间内发送了多少请求:
# Python:打印请求时间间隔import timeimport logging
logging.basicConfig(level=logging.INFO)logger = logging.getLogger(__name__)
def send_request(): start = time.time() # ... 发送请求 ... elapsed = time.time() - start logger.info(f"Request completed in {elapsed:.2f}s")3. 检查额度使用情况
在管理后台查看该 Key 的额度使用情况,确认是否已用尽。
解决方案
降低请求频率
在请求之间添加延迟:
import time
for item in batch: response = send_request(item) time.sleep(1) # 每秒最多一个请求实现指数退避
在收到 429 错误后,自动等待并重试,每次等待时间按指数增长:
import timeimport requests
def request_with_retry(url, headers, data, max_retries=5): for attempt in range(max_retries): response = requests.post(url, headers=headers, json=data)
if response.status_code == 429: retry_after = int(response.headers.get("Retry-After", 2 ** attempt)) print(f"Rate limited. Waiting {retry_after}s before retry {attempt + 1}/{max_retries}") time.sleep(retry_after) continue
return response
raise Exception(f"Max retries ({max_retries}) exceeded")// JavaScript:指数退避重试async function requestWithRetry(url, headers, data, maxRetries = 5) { for (let attempt = 0; attempt < maxRetries; attempt++) { const response = await fetch(url, { method: "POST", headers: headers, body: JSON.stringify(data), });
if (response.status === 429) { const retryAfter = parseInt(response.headers.get("Retry-After") || Math.pow(2, attempt)); console.log(`Rate limited. Waiting ${retryAfter}s before retry ${attempt + 1}/${maxRetries}`); await new Promise(resolve => setTimeout(resolve, retryAfter * 1000)); continue; }
return response; } throw new Error(`Max retries (${maxRetries}) exceeded`);}控制并发请求数
使用信号量或队列限制同时进行的请求数:
# Python:使用信号量控制并发import asyncioimport aiohttp
semaphore = asyncio.Semaphore(3) # 最大并发 3
async def send_request(session, url, data): async with semaphore: async with session.post(url, json=data) as response: return await response.json()升级套餐
如果业务需求需要更高的请求频率或并发量:
- 在管理后台查看当前套餐的限流配置
- 联系管理员升级套餐或调整限流参数
- 询问是否支持为特定 Key 单独配置更高的限流
批量处理请求
如果发送大量独立请求,考虑批量处理以减少请求总数:
- 将多个消息合并到一个 Chat 请求中
- 使用批量接口(如可用)
- 在本地缓存结果,避免重复请求