Java高频面试题:RabbitMQ如何实现消息的持久化?

大家好,我是锋哥。今天分享关于【Java高频面试题:RabbitMQ如何实现消息的持久化?】**面试题。**希望对大家有帮助;

Java高频面试题:RabbitMQ如何实现消息的持久化?

在 RabbitMQ 中,消息持久化的目的是确保在服务器宕机或重启后,消息不会丢失。要实现消息持久化,需要同时设置队列持久化消息持久化

1. 队列持久化(Durable Queue)

队列持久化确保队列在RabbitMQ重启后仍然存在。

2. 消息持久化(Persistent Message)

消息持久化保证消息被持久化到磁盘,即使 RabbitMQ 宕机或重启,消息也不会丢失。

Java 代码实现 RabbitMQ 消息持久化

假设你已经引入了 rabbitmq-client 的 Maven 依赖:

复制代码
<dependency>
    <groupId>com.rabbitmq</groupId>
    <artifactId>amqp-client</artifactId>
    <version>5.13.0</version>
</dependency>

1. 创建持久化队列和持久化消息

生产者代码
复制代码
import com.rabbitmq.client.*;

public class PersistentProducer {
    private final static String QUEUE_NAME = "task_queue";

    public static void main(String[] argv) throws Exception {
        // 创建连接和频道
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("localhost");
        try (Connection connection = factory.newConnection(); 
             Channel channel = connection.createChannel()) {

            // 声明持久化队列
            channel.queueDeclare(QUEUE_NAME, true, false, false, null);

            // 创建持久化消息
            String message = "Hello World!";
            channel.basicPublish("", QUEUE_NAME, 
                                 new AMQP.BasicProperties.Builder()
                                     .deliveryMode(2)  // 2表示持久化消息
                                     .build(), 
                                 message.getBytes());

            System.out.println("Sent: " + message);
        }
    }
}
消费者代码
复制代码
import com.rabbitmq.client.*;

public class PersistentConsumer {
    private final static String QUEUE_NAME = "task_queue";

    public static void main(String[] argv) throws Exception {
        // 创建连接和频道
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("localhost");
        try (Connection connection = factory.newConnection(); 
             Channel channel = connection.createChannel()) {

            // 声明持久化队列
            channel.queueDeclare(QUEUE_NAME, true, false, false, null);

            // 创建消费者
            System.out.println(" [*] Waiting for messages. To exit press Ctrl+C");

            // 自动确认消息
            DeliverCallback deliverCallback = (consumerTag, delivery) -> {
                String message = new String(delivery.getBody(), "UTF-8");
                System.out.println(" [x] Received: " + message);
            };

            channel.basicConsume(QUEUE_NAME, true, deliverCallback, consumerTag -> { });
        }
    }
}

解释

生产者代码
  1. 队列声明 :使用 channel.queueDeclare(QUEUE_NAME, true, false, false, null),其中 true 表示队列是持久化的。
  2. 消息发布 :通过 channel.basicPublish 发布消息时,设置 deliveryMode=2 来确保消息是持久化的。deliveryMode=2 表示消息会写入磁盘,deliveryMode=1 则是非持久化消息(默认)。
消费者代码
  1. 队列声明 :消费端同样需要声明队列为持久化的,channel.queueDeclare(QUEUE_NAME, true, false, false, null)
  2. 消息消费 :通过 channel.basicConsume 来消费消息,RabbitMQ会确保消息持久化,且不会丢失。

2. 其他相关设置

消费者确认(ACK)

消息的持久化保证了消息不丢失,但消费者需要正确地确认消息(ack)。如果你希望RabbitMQ等待消费者确认消息,可以通过设置 autoAck 参数为 false 来实现手动确认。

复制代码
// 启用手动确认
channel.basicConsume(QUEUE_NAME, false, deliverCallback, consumerTag -> { });

然后,在消息处理完成后,使用 channel.basicAck 手动确认:

复制代码
channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);

如果你不确认消息,RabbitMQ会将未确认的消息重新放回队列。


3. 最后总结下

  1. 队列持久化 :在声明队列时,设置 durable=true
  2. 消息持久化 :在发布消息时,设置 deliveryMode=2
  3. 手动确认 :如果你需要确认消息的消费,设置 autoAck=false,并手动调用 channel.basicAck

通过这种方式,RabbitMQ可以确保消息在系统崩溃后不会丢失。

相关推荐
Alex Gram4 分钟前
双机热备软件哪个好
java·系统架构·c#·keepalived·高可用·双机热备·双机热备软件
末代iOS程序员华仔4 分钟前
OPC + Flutter + Swift:跨平台应用上架与专业知识点获客实战指南
开发语言·flutter·swift
脚踏实地皮皮晨5 分钟前
003004002_UniformGrid控件的使用方法
开发语言·c#·.net·wpf·visual studio
纳兰青华9 分钟前
拼图大师:从“暴力尝试“到“动态规划“的拆字艺术
java·算法·动态规划
j7~1 小时前
【Linux】二十六.线程篇三《Linux多线程编程:线程控制、线程ID以及进程地址空间分布、线程局部存储__thread以及clone系统调用》---详解
linux·运维·服务器·开发语言·c++·多线程编辑·线程的控制
维吉斯蔡9 小时前
【VS Code / Cursor】文件夹右键快捷打开与文件类型自动关联
开发语言·程序人生·学习方法
蓝斯4979 小时前
[原创]《C#高级GDI+实战:从零开发一个流程图》第章:增加贝塞尔曲线,上、下、左、右连接点
java·c#·流程图
前端工作日常9 小时前
我学习到的Java 的 Service 分层:itf 和 impl 到底是什么?
java·后端
都叫我大帅哥10 小时前
Spring @Transactional 注解完全指南
java·spring
Java成神之路-10 小时前
G1 垃圾回收器 :SATB + TAMS核心机制深度解析
java·jvm