在 Linux 环境下,RabbitMQ“丢消息”通常不是 RabbitMQ 本身无故丢失,而是配置或使用方式不当导致的。下面按常见原因 → 原理 → 解决办法来说明。
现象:RabbitMQ 重启后消息没了
原因:
durable=truedelivery_mode=2(持久消息)示例(错误):
channel.queueDeclare("queue", false, false, false, null);
channel.basicPublish("", "queue", null, msg.getBytes());
正确做法:
channel.queueDeclare("queue", true, false, false, null);
AMQP.BasicProperties props =
new AMQP.BasicProperties.Builder()
.deliveryMode(2)
.build();
channel.basicPublish("", "queue", props, msg.getBytes());
✅ 持久化 ≠ 不丢,但能防重启丢失
现象:代码以为发送成功,其实 RabbitMQ 没收到
原因:
basicPublish解决:开启 Publisher Confirm
channel.confirmSelect();
channel.basicPublish(...);
channel.waitForConfirmsOrDie();
✅ 强烈建议生产环境必须开 Confirm
现象:消费者一收到消息就“消失”
原因:
boolean autoAck = true;
channel.basicConsume(queue, autoAck, consumer);
消费者还没处理完就崩了 → 消息被 RabbitMQ 认为已消费
解决:
boolean autoAck = false;
channel.basicConsume(queue, autoAck, consumer);
// 处理成功后再:
channel.basicAck(deliveryTag, false);
现象:突发流量后消息丢失
原因:
vm_memory_high_watermarkdisk_free_limitRabbitMQ 会:
检查:
rabbitmqctl status
日志中常见:
memory alarm
disk free space low
解决:
现象:消息“发了但收不到”
原因:
排查:
rabbitmqctl list_queues
rabbitmqctl list_bindings
现象:机器重启,全部消息没了
解决:
rabbitmqctl list_queues name messages_ready messages_unacknowledged
messages_ready:等消费messages_unacknowledged:已发但未 ACK✅ 队列持久
✅ 消息持久
✅ Publisher Confirm
✅ 手动 ACK
✅ Quorum / 镜像队列
✅ 监控内存 & 磁盘
如果你愿意,可以贴:
我可以帮你精准定位是哪一类丢消息。