用 20 个线程同时调 qwen-plus 做批量翻译,返回 429,code 是 Throttling.RateQuota,message 提示 Requests rate limit exceeded,把线程降到 5 个后基本不再出现。
一开始怀疑是「子账号与主账号共享同一份配额」,查了一圈,方向不对。
真正麻烦的地方在于,几个原因的现象几乎一样。账号的每分钟请求数被瞬间打满。另一种情况是线程池并发数远高于账号允许的并发上限。
不容易想到的是,重试请求叠加进去,实际速率翻了一倍。
第一件事是把并发压到可控范围再观察错误率
python -c "from concurrent.futures import ThreadPoolExecutor;print(ThreadPoolExecutor(max_workers=4))"
接着改用批量接口,把多条文本合并成一次调用
curl https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions -H "Authorization: Bearer $DASHSCOPE_API_KEY" -d '{"model":"qwen-plus","messages":[{"role":"user","content":"hi"}]}'
再往下对 429 单独做退避,其余错误直接失败
if 'Throttling' in err: time.sleep(3)
末了把每分钟实际请求数打成指标观察
print({'rpm': count, 'errors': errs})
改完先别撤,确认这几项。批量任务跑完,429 只有零星几次,平均耗时没有明显上升,失败重试次数控制在个位数。
限流既看 QPS 也看并发,短时间突发即使总量不大也会触发,节奏要拉平而不是靠重试硬顶,否则重试流量本身就会持续顶满。线上能稳定复现的问题都不算难,难的是只在大流量下才出现的那种。