【RabbitMQ】高级特性—持久性、重试机制详解

【RabbitMQ】高级特性—持久性、重试机制详解

持久性

我们在前面说了消息端处理消息时,消息如何不丢失,但是如何保证当 RabbitMQ 服务器停掉之后,生产者发送的消息不丢失呢?

默认情况下,RabbitMQ 退出或者由于某种原因崩溃时,会忽视队列和消息,除非告知他不要这么做

RabbitMQ 的持久化分为三个部分:

  • 交换器的持久化
  • 队列的持久化
  • 消息的持久化

交换机持久化

交换机的持久化,是通过在声明交换机时将 durable 参数置为 true 实现的

  • 相当于将交换机的属性在服务器内部保存,当 MQ 的服务器发生意外或关闭之后,重启 RabbitMQ 时不需要重新去建立交换机,交换机会自动建立,相当于一直存在
  • 如果交换器不设置持久化,那么在 RabbitMQ 服务器重启之后,相关的交换机元数据会丢失,对一个长期使用的交换机来说,建议将其置为持久化的
ExchangeBuilder.topicExchange(Constant.ACK_EXCHANGE_NAME).durable(true).build();

队列持久化

队列的持久化是通过在声明队列时将 durable 参数置为 true 实现的

  • 如果队列不设置持久化,那么在 RabbitMQ 服务器重启之后,该队列就会被删除掉,此时数据也会丢失(队列没有了,消息也无处可存了)
  • 队列的持久化能保证该队列本身的元数据不会因异常情况而丢失,但是并不能保证内部存储的消息不会丢失
  • 要确保消息不会丢失,需要将消息设置为持久化

咱们前面用的创建队列的方式都是持久化的

QueueBuilder.durable(COnstant.ACK_QUEUE).build();

点进去看源码会发现,该方法默认 durabletrue

public static QueueBuilder durable() {
   
     
    return durable(namingStrategy.generateName());  
}  
  
private QueueBuilder setDurable() {
   
     
    this.durable = true;  
    return this;  
}

通过下面代码,可以创建非持久化的队列

QueueBuilder.noDurable(Constant.ACK_QUEUE).build();

消息持久化

消息实现持久化,需要把消息的投递模式 (MessageProperties 中的 deliveryMode)设置为 2,也就是 MessageDeliveryMode.PERSISTENT

public enum MessageDeliveryMode {
   
     
    NON_PERSISTENT,  
    PERSISTENT;

设置了队列和消息的持久化,当 RabbitMQ 服务器重启之后,消息依旧存在。

  • 如果只设置队列持久化,重启之后消息会丢失
  • 如果只设置消息持久化,重启之后队列消息,继而消息也丢失
    所以单单设置消息持久化而不设置队列的持久化显得毫无意义
// 非持久化信息
channel.basicPublish("", QUEUE_NAME, null, msg.getBytes());

// 持久化信息
channel.basicPublish("", QUEUE_NAME,
转载请说明出处内容投诉
CSS教程网 » 【RabbitMQ】高级特性—持久性、重试机制详解

发表评论

欢迎 访客 发表评论

一个令你着迷的主题!

查看演示 官网购买