RabbitMQ交换机、队列、消息持久化

📅 2026/7/14 23:18:50
RabbitMQ交换机、队列、消息持久化
RabbitMQ 持久化与非持久化在 RabbitMQ 中持久化决定了 Broker 重启后交换机、队列和消息是否还能保留。理解这三层持久化机制是构建可靠消息系统的基本功。本文分两部分说明非 Spring 环境使用原生rabbitmq-clientSpring 环境使用 Spring AMQP一、核心概念RabbitMQ 的持久化分为三个独立层面三者互不影响需要分别配置层级作用Broker 重启后交换机持久化交换机元数据是否写入磁盘非持久化交换机会消失队列持久化队列元数据是否写入磁盘非持久化队列会消失消息持久化消息体是否写入磁盘非持久化消息会丢失重要只有交换机、队列、消息三者都持久化才能保证 Broker 重启后消息不丢失。只持久化队列、不持久化消息队列还在但里面的消息仍会丢失。二、非 Spring 环境原生 Java Client2.1 队列持久化第二个参数// 持久化队列durable true—— 重启后队列仍在channel.queueDeclare(my.queue,true,false,false,null);// 非持久化队列durable false—— 重启后队列消失channel.queueDeclare(my.queue,false,false,false,null);queueDeclare参数说明参数持久化非持久化durabletruefalse重启后队列保留队列删除2.2 交换机持久化importcom.rabbitmq.client.BuiltinExchangeType;// 非持久化交换机默认—— 重启后交换机消失channel.exchangeDeclare(my.exchange,BuiltinExchangeType.DIRECT);// 持久化交换机durable true—— 重启后交换机仍在channel.exchangeDeclare(my.exchange,BuiltinExchangeType.DIRECT,true);// 完整参数写法// exchangeDeclare(name, type, durable, autoDelete, arguments)channel.exchangeDeclare(my.exchange,BuiltinExchangeType.TOPIC,true,false,null);参数持久化非持久化durabletruefalse默认重启后交换机保留交换机删除2.3 消息持久化消息持久化通过BasicProperties的deliveryMode控制importcom.rabbitmq.client.AMQP;// 非持久化消息默认deliveryMode 1—— 重启后消息丢失channel.basicPublish(,my.queue,null,临时消息.getBytes());// 持久化消息deliveryMode 2—— 重启后消息保留AMQP.BasicPropertiespropsnewAMQP.BasicProperties.Builder().deliveryMode(2)// 2 持久化1 非持久化.build();channel.basicPublish(,my.queue,props,重要消息.getBytes());deliveryMode含义重启后1默认非持久化TRANSIENT消息丢失2持久化PERSISTENT消息保留2.4 完整示例全持久化 vs 全非持久化// 全持久化生产环境推荐 // 持久化交换机channel.exchangeDeclare(order.exchange,BuiltinExchangeType.DIRECT,true);// 持久化队列channel.queueDeclare(order.queue,true,false,false,null);channel.queueBind(order.queue,order.exchange,order.create);// 持久化消息AMQP.BasicPropertiespersistentPropsnewAMQP.BasicProperties.Builder().deliveryMode(2).build();channel.basicPublish(order.exchange,order.create,persistentProps,订单数据.getBytes());// 全非持久化临时/测试场景 // 非持久化交换机channel.exchangeDeclare(temp.exchange,BuiltinExchangeType.FANOUT,false);// 非持久化队列channel.queueDeclare(temp.queue,false,false,false,null);channel.queueBind(temp.queue,temp.exchange,);// 非持久化消息channel.basicPublish(temp.exchange,,null,临时日志.getBytes());三、Spring 环境Spring AMQP3.1 队列持久化importorg.springframework.amqp.core.Queue;importorg.springframework.amqp.core.QueueBuilder;// 持久化队列BeanpublicQueuedurableQueue(){returnQueueBuilder.durable(my.queue).build();}// 非持久化队列BeanpublicQueuenonDurableQueue(){returnQueueBuilder.nonDurable(my.queue).build();}// 等价写法BeanpublicQueuedurableQueue2(){returnnewQueue(my.queue,true);// 第二个参数 durable}BeanpublicQueuenonDurableQueue2(){returnnewQueue(my.queue,false);}3.2 交换机持久化importorg.springframework.amqp.core.*;// 持久化交换机默认 durable trueBeanpublicDirectExchangedurableExchange(){returnExchangeBuilder.directExchange(my.exchange).durable(true).build();}// 非持久化交换机BeanpublicFanoutExchangenonDurableExchange(){returnExchangeBuilder.fanoutExchange(my.exchange).durable(false).build();}// 等价写法BeanpublicTopicExchangedurableTopic(){returnnewTopicExchange(my.exchange,true,false);// durabletrue, autoDeletefalse}BeanpublicTopicExchangenonDurableTopic(){returnnewTopicExchange(my.exchange,false,false);}3.3 消息持久化方式一MessageProperties设置importorg.springframework.amqp.core.Message;importorg.springframework.amqp.core.MessageDeliveryMode;importorg.springframework.amqp.core.MessageProperties;importorg.springframework.amqp.rabbit.core.RabbitTemplate;// 持久化消息MessagePropertiespropsnewMessageProperties();props.setDeliveryMode(MessageDeliveryMode.PERSISTENT);MessagemessagenewMessage(重要消息.getBytes(),props);rabbitTemplate.send(my.exchange,routing.key,message);// 非持久化消息MessagePropertiestransientPropsnewMessageProperties();transientProps.setDeliveryMode(MessageDeliveryMode.NON_PERSISTENT);MessagetransientMsgnewMessage(临时消息.getBytes(),transientProps);rabbitTemplate.send(my.exchange,routing.key,transientMsg);方式二RabbitTemplate发送时指定// 发送持久化消息Spring 默认 deliveryMode PERSISTENTrabbitTemplate.convertAndSend(my.exchange,routing.key,Hello);// 单条消息指定非持久化rabbitTemplate.convertAndSend(my.exchange,routing.key,临时消息,message-{message.getMessageProperties().setDeliveryMode(MessageDeliveryMode.NON_PERSISTENT);returnmessage;});rabbitTemplate.send()和rabbitTemplate.convertAndSend()区别:是Message类,可以直接send,无论是不是Message类,都会转换成Message类,可以通用rabbitTemplate.convertAndSend()3.4 Spring 完整配置示例ConfigurationpublicclassRabbitMQConfig{// 持久化配置生产推荐 BeanpublicDirectExchangeorderExchange(){returnExchangeBuilder.directExchange(order.exchange).durable(true).build();}BeanpublicQueueorderQueue(){returnQueueBuilder.durable(order.queue).build();}BeanpublicBindingorderBinding(QueueorderQueue,DirectExchangeorderExchange){returnBindingBuilder.bind(orderQueue).to(orderExchange).with(order.create);}// 非持久化配置临时/测试 BeanpublicFanoutExchangetempExchange(){returnExchangeBuilder.fanoutExchange(temp.exchange).durable(false).build();}BeanpublicQueuetempQueue(){returnQueueBuilder.nonDurable(temp.queue).build();}BeanpublicBindingtempBinding(QueuetempQueue,FanoutExchangetempExchange){returnBindingBuilder.bind(tempQueue).to(tempExchange);}}RestControllerpublicclassProducerController{AutowiredprivateRabbitTemplaterabbitTemplate;// 发送持久化消息GetMapping(/send/persistent)publicStringsendPersistent(){rabbitTemplate.convertAndSend(order.exchange,order.create,订单数据);return持久化消息已发送;}// 发送非持久化消息GetMapping(/send/transient)publicStringsendTransient(){rabbitTemplate.convertAndSend(temp.exchange,,临时日志,msg-{msg.getMessageProperties().setDeliveryMode(MessageDeliveryMode.NON_PERSISTENT);returnmsg;});return非持久化消息已发送;}}四、对照总结对象非 Spring原生 ClientSpring AMQP队列持久化queueDeclare(name, true, ...)QueueBuilder.durable(name)队列非持久化queueDeclare(name, false, ...)QueueBuilder.nonDurable(name)交换机持久化exchangeDeclare(name, type, true, ...)ExchangeBuilder.xxxExchange(name).durable(true)交换机非持久化exchangeDeclare(name, type, false, ...)ExchangeBuilder.xxxExchange(name).durable(false)消息持久化props.deliveryMode(2)MessageDeliveryMode.PERSISTENT消息非持久化props为null或deliveryMode(1)MessageDeliveryMode.NON_PERSISTENT五、注意事项三者缺一不可队列持久化 消息持久化才能保证重启后消息不丢交换机持久化保证路由结构不丢。性能权衡持久化会写磁盘吞吐量低于非持久化。日志、监控等可非持久化订单、支付等应全持久化。不能修改已有声明已声明为非持久化的队列/交换机不能通过修改参数变成持久化需要删除后重新声明。持久化不等于不丢还需配合手动确认Ack、生产者 Confirm 等机制才能构建完整的消息可靠性方案。Spring 默认值DirectExchange、TopicExchange等默认durable trueRabbitTemplate默认发送持久化消息。