接口已经返回bulk_uuid,调用方也收到202,但几个小时后状态仍是open,商品没有更新。此时HTTP请求早已结束,真正工作由消息队列完成;继续重发Bulk只会制造更多积压。

先查这一个UUID

SELECT uuid,description,start_time,user_id,operation_count
FROM magento_bulk WHERE uuid='YOUR-BULK-UUID';

SELECT status,error_code,SUBSTRING(result_message,1,500),topic_name
FROM magento_operation WHERE bulk_uuid=(SELECT bulk_id FROM magento_bulk WHERE uuid='YOUR-BULK-UUID')
ORDER BY id;

不同版本字段可能略有差异,先 DESCRIBE magento_bulk 与 magento_operation。不要直接把status改成complete,这只会伪造结果。

找到topic对应的Consumer

bin/magento queue:consumers:list
bin/magento queue:consumers:start async.operations.all --max-messages=1000

命令前台运行时观察var/log与终端错误。若能处理,说明Supervisor或Cron没有保持Consumer运行;若立即退出,检查queue_consumer.xml、communication.xml和env.php里的AMQP连接。

RabbitMQ层面

  • 在RabbitMQ管理页看ready与unacked数量;
  • 确认虚拟主机、用户名权限与Magento env.php一致;
  • 队列有ready但Consumer为0:进程未启动;
  • unacked长期不降:处理函数阻塞或超时;
  • 队列为空但operation仍open:topic路由或数据库记录生成阶段有问题。

让Supervisor稳定运行

command=php /path/bin/magento queue:consumers:start async.operations.all --single-thread --max-messages=10000
autostart=true
autorestart=true
stopwaitsecs=60

路径、运行用户、PHP版本和环境变量必须与Web进程一致。设置max-messages让进程定期退出释放内存,再由Supervisor拉起。

补救已有批次

修好Consumer后先让原消息继续消费,按operation结果只重试失败项。业务侧保存每个item与operation_key的对应关系,并使用幂等键,避免整批重发产生重复商品或重复库存变更。