[mq]RabbitMQ,RocketMQ,Kafka,Pulsar,4种mq如何保证消息的可靠性

2 阅读2分钟

juejin.cn/post/739116…

RabbitMQ消息的可靠性

在RabbitMQ中,消息的可靠性传输可以通过以下几种机制来保证:

  1. 持久化:确保消息在RabbitMQ重启后不会丢失。
  2. 确认机制:确保消息从生产者到RabbitMQ以及从RabbitMQ到消费者都被成功处理。
  3. 重试机制:处理消息消费失败后的重试和死信队列(DLX)。

以下是一些关键机制和相应的Java代码片段:

1. 持久化(Durability)

持久化包括将队列和消息设置为持久化,这样在RabbitMQ重启后消息仍然存在。

// 声明持久化队列
boolean durable = true;
channel.queueDeclare(QUEUE_NAME, durable, false, false, null);
String message = "Hello, RabbitMQ!";
// 发送持久化消息
channel.basicPublish("", QUEUE_NAME, MessageProperties.PERSISTENT_TEXT_PLAIN, message.getBytes("UTF-8"));

2. 确认机制(Acknowledgements)

RabbitMQ提供了手动ACK机制。

生产者确认(Publisher Confirms)和消费者确认(Consumer Acknowledgements)机制。

生产者确认

生产者可以开启确认模式,确保消息已被RabbitMQ消息队列接收到并持久化。

channel.queueDeclare(QUEUE_NAME, true, false, false, null);
channel.confirmSelect();//启用了生产者确认模式
String message = "Hello, RabbitMQ!";
channel.basicPublish("", QUEUE_NAME, MessageProperties.PERSISTENT_TEXT_PLAIN, message.getBytes("UTF-8"));

消费者确认

消费者可以在处理完消息后发送确认信号,以确保消息被成功处理。

// 处理消息
try {
    doWork(message);
} finally {
System.out.println(" [x] Done");
    // 消费者手动确认消息
    channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
}
};
boolean autoAck = false; // 自动确认关闭
channel.basicConsume(QUEUE_NAME, autoAck, deliverCallback, consumerTag -> { });

3. 重试机制和死信队列(DLX)

RabbitMQ支持死信队列(Dead Letter Exchange),可以将处理失败的消息重新路由到另一个死信队列。


try (Connection connection = factory.newConnection(); Channel channel = connection.createChannel()) {
    // 声明死信队列
    channel.queueDeclare(DLX_NAME, true, false, false, null);

    Map<String, Object> args = new HashMap<>();
    args.put("x-dead-letter-exchange", "");
    // 设置队列的参数,使其使用死信交换器
    args.put("x-dead-letter-routing-key", DLX_NAME);

    // 声明正常队列,并绑定死信队列
    channel.queueDeclare(QUEUE_NAME, true, false, false, args);

    String message = "Hello, RabbitMQ!";
    channel.basicPublish("", QUEUE_NAME, MessageProperties.PERSISTENT_TEXT_PLAIN, message.getBytes("UTF-8"));
}
}
}

消费者可以通过channel.basicReject或channel.basicNack拒绝消息,并设置requeue参数为false,使消息进入死信队列。

// 拒绝消息并不重新入队
channel.basicReject(deliveryTag, false);

RocketMQ消息的可靠性

在RocketMQ中,消息的可靠性传输可以通过以下几种机制来保证:

  1. 消息持久化:确保消息在Broker重启后不会丢失。

  2. 同步刷盘:确保消息持久化到磁盘后才确认。

  3. 消息确认机制:确保消息被正确处理。

  4. 重试机制和死信队列:处理消息发送失败后的重试和死信队列(DLX)。

kafka消息的可靠性