RabbitMQ-消息可靠性-publisher-confirm持久化与手动ack

RabbitMQ 消息可靠性:publisher confirm、持久化与手动 ack

消息发出去不代表到了。本文梳理 RabbitMQ 消息丢失的三个环节(发布端、Broker、消费端),并给出 publisher confirm、持久化和手动 ack 的完整可靠性方案。

一、问题案例

订单服务通过 RabbitMQ 发「下单成功」消息给下游,偶尔下游说没收到,订单状态对不上。查日志,发布端明明「发送成功」了,消费者却没消费。

java 复制代码
rabbitTemplate.convertAndSend("order.exchange", "order.create", msg);
// 返回了,就以为发出去了

二、原理详解:消息丢失的三个环节

消息丢失可能发生在三个环节:

  1. 发布端 → Broker :没开 publisher confirm,convertAndSend 只是「发出去就返回」,不保证 Broker 真的收到。exchange 名字写错、路由不到队列,消息直接丢,发布端无感。
  2. Broker 内部:exchange / 队列没有持久化,Broker 重启后消息丢失。
  3. Broker → 消费者:没有手动 ack,消费者拿到消息就丢;或者 ack 策略不对,导致重复投递混乱。

三、实战代码:可靠性三件套

发布端开 confirm + return:

yaml 复制代码
spring.rabbitmq.publisher-confirm-type: correlated
spring.rabbitmq.publisher-returns: true

队列和消息持久化:

java 复制代码
// 声明持久化队列
new Queue("order.queue", true);

// 发送时消息持久化
Message message = MessageBuilder.withBody(payload)
        .setDeliveryMode(MessageDeliveryMode.PERSISTENT)
        .build();

消费者手动 ack:

yaml 复制代码
spring.rabbitmq.listener.simple.acknowledge-mode: manual
java 复制代码
@RabbitListener(queues = "order.queue")
public void onMessage(Message message, Channel channel) throws IOException {
    try {
        // 处理业务
        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
    } catch (Exception e) {
        channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true);
    }
}

四、常见踩坑

  • confirm 后仍可能重复投递:确认只保证「Broker 收到了」,不保证「只投递一次」,消费端要做幂等。
  • 可靠性是组合拳:发送确认 + 持久化 + 手动 ack + 幂等,缺一环就可能丢消息或重复消费。

五、总结

  • 消息丢失有三环:发布端、Broker、消费端,都要防。
  • confirm + 持久化 + 手动 ack,三件套缺一不可。
  • 消费端幂等,兜底重复投递。

我是无羡(小剑),全栈偏后端的独立开发者。

作品集:无羡 · 独立开发者作品集

如果对你有帮助,欢迎点赞、收藏、关注。

相关推荐
我也要在julius_bar里藏钱1 小时前
【山竹记账后端】1.搭建后端项目
后端·ruby·rails
吃饱了得干活1 小时前
一个订单的奇幻漂流:RabbitMQ 五大难题实战
spring boot·后端·rabbitmq
比奥利奥还傲.5 小时前
哪吒监控面板实战:部署 Dashboard、接入 Agent、钉钉告警,再配置固定公网访问
网络·人工智能·分布式·1024程序员节
拼图20914 小时前
Git常用语法
分布式·git·学习
雨会停rain1 天前
rabbitmq 创建独立管理员账号,禁用默认 admin
rabbitmq
xbgRS1 天前
RabbitMQ高级特性
rabbitmq
盟道科技1 天前
小程序订阅消息大规模投递实践:频控令牌池、Redis限流与失败补偿设计
分布式·算法·小程序
卷毛的技术笔记1 天前
RocketMQ事务消息:我把分布式事务这层窗户纸捅破了
java·分布式·后端·java-rocketmq
吃饱了得干活2 天前
RabbitMQ 原理解析(下):存储、集群与可靠投递
后端·rabbitmq