要让rabbitmq在宕机重启后不丢数据,必须同时配置交换器持久化(durable=true)、队列持久化(durable=true)和消息持久化(deliverymode=2),三者缺一不可;仅配置其中一项无法保证消息不丢失。

要让 RabbitMQ 在宕机重启后不丢数据,必须同时配置队列持久化和消息持久化。只做其中一项是无效的——比如队列设为 durable 但消息不持久,重启后队列还在,但里面的消息全没了。
队列持久化(durable = true)
队列持久化确保队列元数据(名称、类型、绑定关系等)写入磁盘,服务重启后队列依然存在。
- 使用原生客户端时,在
queueDeclare中第二个参数设为true:
channel.queueDeclare("my_queue", true, false, false, null);
- 使用 Spring AMQP 时,通过
QueueBuilder.durable("my_queue")或构造函数显式指定:
new Queue("my_queue", true);
- 注意:如果之前已声明过同名非持久化队列,需先删除旧队列或改用新队列名,否则会报错。
交换器持久化(durable = true)
交换器不持久化,重启后路由规则丢失,生产者发消息会失败(AMQP 404 错误)。
在 Linux 上通过 Docker 运行 OpenClaw,并使用 Tailscale 实现远程访问。⚠️ 涉及 sudo、Docker、Tailscale和凭证挂载——请先查阅安全章节...
- 原生客户端:
channel.exchangeDeclare("my_exchange", "topic", true);
- Spring AMQP:
new TopicExchange("my_exchange", true, false);
消息持久化(deliveryMode = 2)
消息本身必须标记为持久,RabbitMQ 才会将其同步刷入磁盘。仅靠队列和交换器持久化无法保存消息体。
- 原生客户端发送时,第三个参数传入
MessageProperties.PERSISTENT_TEXT_PLAIN(等价于 deliveryMode=2):
channel.basicPublish("my_exchange", "routing.key", MessageProperties.PERSISTENT_TEXT_PLAIN, "hello".getBytes());
- Spring AMQP 默认已启用消息持久化(
convertAndSend内部自动设置 deliveryMode=2),无需额外配置;但前提是队列和交换器已声明为 durable。
关键提醒与常见误区
三者缺一不可:交换器 durable + 队列 durable + 消息 deliveryMode=2,才算完整持久化链路。
- 消息持久化不是“绝对保险”:若刚写入内存、尚未落盘时发生断电或强制 kill,仍可能丢失。如需更强保障,需配合发布确认(publisher confirms)+ 事务(不推荐)或镜像队列。
- 性能影响:持久化会降低吞吐量,因涉及磁盘 I/O。高并发场景可评估是否启用惰性队列(lazy queue)替代部分场景。
- RabbitMQ Web 控制台中,持久化队列/交换器右侧会显示 “D” 标识,可直观验证配置是否生效。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










