必须同时配置交换器持久化(durable=true)、队列持久化(durable=true)和消息持久化(deliveryMode=2),三者缺一不可;仅配置其中一项无法防止RabbitMQ重启后消息丢失。

要在 RabbitMQ 服务重启后不丢消息,必须同时满足三个条件:交换器持久化、队列持久化、消息本身标记为持久化。只做其中一项,数据依然会丢失。
交换器必须声明为 durable
交换器不持久化,重启后就不存在了,生产者发消息会直接报 AMQP 404 错误,路由失败。
- 原生客户端:调用
channel.exchangeDeclare("my-exchange", "topic", true),第三个参数设为 true - Spring AMQP:使用
new TopicExchange("my-exchange", true, false)或@Bean方式配置时显式传入 durable = true - 注意:若之前创建过同名非持久化交换器,需先删除或改名,否则声明会失败
队列必须声明为 durable
队列持久化保证其元数据(名称、类型、绑定关系)写入磁盘,重启后队列仍存在,但仅此一项不能保住里面的消息。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 原生客户端:
channel.queueDeclare("my-queue", true, false, false, null),第二个参数为 true - Spring AMQP:
new Queue("my-queue", true)或QueueBuilder.durable("my-queue") - 已有非持久化同名队列时,必须先清理旧队列,否则抛出
IOException
发送消息时必须设置 deliveryMode=2
这是真正把消息体写入磁盘的关键一步。即使交换器和队列都持久化了,消息若没标记持久,RabbitMQ 仍只存内存,宕机即丢。
立即学习“Java免费学习笔记(深入)”;
- 原生客户端:用
MessageProperties.PERSISTENT_TEXT_PLAIN(等价于deliveryMode=2)作为basicPublish的 props 参数 - Spring AMQP:
rabbitTemplate.convertAndSend(...)默认已启用消息持久化,前提是交换器和队列已正确声明为 durable - 不要依赖自动配置——务必验证你使用的 Exchange 和 Queue Bean 确实设置了 durable=true
补充提醒:持久化不是万能保险
即使三者全配,极端情况下(如消息刚写入内存、尚未刷盘时断电或强制 kill)仍可能丢失。如需更高可靠性:
- 开启发布确认(publisher confirms),确保消息已成功落盘再返回 ACK
- 消费者端配合手动确认(manual ack),避免消息被取走却未处理完就丢失
- 避免使用事务(性能差,已不推荐)
- 生产环境建议搭配镜像队列或集群部署提升容灾能力

















