这类问题我又碰上了一次。八个 Celery worker 各自每秒查一次 batch 状态,白天开始大量 429,原文 Rate limit reached for requests,Batch 任务本身没跑几条,额度却被状态查询吃掉了。
第一反应是「轮询间隔固定一秒 没有退避」,验证下来不成立。
把日志和配置对完,能解释这个现象的基本就这几处。状态查询同样计入请求配额;每个 worker 独立轮询 结果没有共享;任务堆积时轮询次数成倍增长。
动手时先统计状态查询请求的占比
python -c "print('count /batches requests in access log')"
接着改成单点轮询并写缓存
python poller.py --interval 30 --store redis --once
随后按批次状态拉长间隔
python poller.py --backoff 1.5 --max-interval 300
worker 只读缓存不再直连接口
python celery_task.py --source cache
我习惯把每一步的执行时间和结果记在一边,后面复盘省事。
改完先别撤,确认这几项。状态查询请求下降九成,429 消失,批次完成时间没有明显变长。
Batch 的便宜是用等待换来的,轮询频率要跟着状态走,多实例场景必须收敛到一个轮询者。同一份配置在测试环境跑通,不代表线上没事,两边的默认值经常不一样。
