RabbitMQ消息持久化
我们看下之前启动idea测试消息发送的时候在后台生成的一条消息,现在已经在消息队列里面还没有被消费。
现在我们重启下RabbitMQ,执行linux命令:docker restart mq
看上图实时显示的错误信息,失去连接了,接下来刷新这个页面,可以发现这个对象没有了。
说明rabbit消息并不会持久化,不仅如此,我们查看下交换机,发现连之前建的交换机都没有了:
那为什么系统交换机还在呢,说明系统交换机持久化了,这就要跟交换机持久化类型有关了,Durability这个属性如果是Durable的就代表是持久化的,如果是Transient的类型的就代表是暂时的。而系统的这些都是带D的,说明它们是持久化的组件。
上面的设置是在网页端设置,如果要在java代码里面怎么设置呢?
生产者确认可以确保消息投递到RabbitMQ的队列中,但是消息发送到RabbitMQ以后,如果突然宕机,也可能导致消息丢失。
要想确保消息在RabbitMQ中安全保存,必须开启消息持久化机制。
- 交换机持久化
- 队列持久化
- 消息持久化
RabbitMQ中交换机默认是非持久化的,mq重启后就丢失。
SpringAMQP中可以通过代码指定交换机持久化:
@Bean
public DirectExchange simpleExchange(){
// 三个参数:交换机名称、是否持久化、当没有queue与其绑定时是否自动删除
return new DirectExchange("simple.direct", true, false);
}
事实上,默认情况下,由SpringAMQP声明的交换机都是持久化的。
上面的是交换机持久化,队列持久化呢?
RabbitMQ中队列默认是非持久化的,mq重启后就丢失。
SpringAMQP中可以通过代码指定交换机持久化:
@Bean
public Queue simpleQueue(){
// 使用QueueBuilder构建队列,durable就是持久化的
return QueueBuilder.durable("simple.queue").build();
}
事实上,默认情况下,由SpringAMQP声明的队列都是持久化的。
可以在RabbitMQ控制台看到持久化的队列都会带上`D`的标示:
利用SpringAMQP发送消息时,可以设置消息的属性(MessageProperties),指定delivery-mode:
- 1:非持久化
- 2:持久化
用java代码指定:
默认情况下,SpringAMQP发出的任何消息都是持久化的,不用特意指定。
为什么默认持久化了还要特意说下呢,因为持久化其实会损失性能,因此有些场合是可以不做消息持久化的,这都是根据业务来的。