问题出现得很突然,日志倒是留得挺全。图片处理任务把原图 base64 后直接写进 RabbitMQ 消息体,单条 9MB,消费者拉取后连接经常超时,队列内存占用涨到 12GB。
刚开始盯着「消费者预取多条大消息把内存打满」,折腾了半个多小时,排掉了。
把日志和配置对完,能解释这个现象的基本就这几处。消息体积超过 broker 的默认帧与内存限制。另一种情况是base64 让体积比原文件膨胀三分之一。
少数情况下是消息未设过期时间,堆积后无法回收。
动手时先看队列里消息的大小分布
rabbitmqctl list_queues name messages message_bytes
接着改为只传对象存储的 key
python -c "import json;print(json.dumps({'bucket':'img','key':'2026/11/a.jpg','op':'resize'}))"
调小预取数量避免一次拉太多
rabbitmqctl set_policy prefetch1 '.*' '{"basic.qos":{"prefetch_count":1}}' --apply-to queues
给消息加 TTL 并清理存量
rabbitmqctl purge_queue img_tasks
别只看报错消失,验证要多做一步。消息体降到 1KB 以内,消费者内存稳定在 400MB,队列积压清零,图片处理耗时与之前持平。
提醒一点。队列只适合传引用不适合传载荷,大对象走对象存储,消息体保持小才是稳定的前提。同一份配置在测试环境跑通,不代表线上没事,两边的默认值经常不一样。
