ps 能看到 Consumer,Supervisor 也显示 RUNNING,但队列里的消息越来越多。RUNNING 只说明进程没退出,不说明它正在处理正确的队列,更不说明处理成功。

十分钟内先拿到四个数字

bin/magento queue:consumers:list
ps -ef | grep '[q]ueue:consumers:start'

# RabbitMQ 环境
rabbitmqctl list_queues name messages_ready messages_unacknowledged consumers

观察十分钟内 Ready、Unacked、Consumer 数和业务成功数。Ready 上升、Unacked 为零:进程可能监听错队列或拿不到消息;Unacked 长期不降:处理函数阻塞;Ready 下降又回升:消息 reject/requeue 或消费者崩溃。

确认进程参数与当前 release

readlink -f /proc/CONSUMER_PID/cwd
tr '�' ' ' < /proc/CONSUMER_PID/cmdline
readlink -f /var/www/current

蓝绿发布后 Supervisor 可能仍运行旧 release 的 Consumer。Web 已经使用新 schema,旧 Consumer 继续反序列化新消息,就会反复失败。部署流程应先优雅停止旧消费者,再从新 release 启动。

前台运行一个有限消费者抓异常

bin/magento queue:consumers:start async.operations.all   --max-messages=10 -vvv

使用实际 consumer 名称,并在测试或维护窗口执行,避免和现有消费者争抢不可重复的消息。与此同时查看:

tail -f var/log/system.log var/log/exception.log
journalctl -u supervisor --since '15 minutes ago'

一个坏消息若每次失败都重新入队,会占满日志和 CPU。捕获 message ID、topic、重试次数和异常类型;payload 可能含客户数据,不要完整打印。

Unacked 不下降时查阻塞点

先对 Consumer 进程抓安全的进程栈/系统调用,再查数据库:

strace -p CONSUMER_PID -f -tt -T -e trace=network,read,write
mysql -e 'SHOW FULL PROCESSLIST'
mysql -e 'SHOW ENGINE INNODB STATUSG'

持续等待同一 SQL,查锁持有者和事务边界;持续等待外部 API,给连接和读取设置超时,并把可重试与永久失败分开。不要直接 kill 数据库会话,先确认它是否正在提交订单或库存事务。

消费者生命周期不能只靠永不退出

env.php 与 Supervisor 中统一 max-messages、内存限制、重启和 stopwaitsecs。有限消息后正常退出再由 Supervisor 拉起,可以释放长期进程中的内存和旧对象,但太小会造成频繁启动。

恢复积压时控制并发

先用一个消费者确认成功率,再逐步扩到安全并发。一次启动几十个进程可能把 RabbitMQ 压力转移到 MySQL 或第三方 API。监控“最老消息年龄”和每分钟成功处理数,直到积压归零;仅看进程数会再次误判。