RabbitMQ重试机制

RabbitMQ 重试机制:Auto 与 Manual 消费模式

在 RabbitMQ 消费端,消息消费失败后的重试策略 直接影响系统的可靠性。Spring AMQP 提供了两种消费模式:Auto 模式(自动确认)Manual 模式(手动确认)

本文详细对比两种模式的差异,重点分析 deliveryTag 的变化规律


一、核心区别:Tag 的变化

模式 重试时 Tag 变化 原因
Auto 模式 Tag 保持不变 内部重试,同一条消息
Manual 模式(入队) Tag 持续增加 重新入队 = 新消息,产生新 Tag

关键理解

  • Auto 模式重试是同一条消息在内部重试,Tag 不变
  • Manual 模式 basicNack(requeue=true)消息重新入队,相当于新消息,Tag 递增

二、Auto 模式(自动确认)

2.1 配置

yaml 复制代码
spring:
  rabbitmq:
    listener:
      simple:
        acknowledge-mode: auto
        retry:
          enabled: true
          max-attempts: 3          # 最大重试次数
          initial-interval: 1000   # 首次重试间隔(毫秒)
          multiplier: 2            # 间隔倍数

2.2 Tag 变化示例

复制代码
消息到达(Tag=1)→ 消费失败 → 重试(Tag=1)→ 消费失败 → 重试(Tag=1)→ 消费成功
       ↑                      ↑                    ↑
       Tag=1                  Tag=1                Tag=1
       同一条消息             同一条消息           同一条消息

2.3 代码示例

java 复制代码
@RabbitListener(queues = "test-queue")
public void onMessage(String message) {
    System.out.println("收到消息: " + message);
    // 消费失败,自动重试
    // Tag 保持不变,始终是同一条消息
    throw new RuntimeException("消费失败");
}

2.4 Auto 模式特点

特点 说明
Tag 不变 重试时 Tag 保持不变,始终是同一条消息
内部重试 Spring 内部处理,不经过队列
自动入队 重试次数耗尽后,消息重新入队
简单易用 代码简洁,无需手动管理

三、Manual 模式(手动确认)

3.1 配置

yaml 复制代码
spring:
  rabbitmq:
    listener:
      simple:
        acknowledge-mode: manual
        prefetch: 1

3.2 Tag 变化示例(入队)

复制代码
消息到达(Tag=1)→ 消费失败 → basicNack(requeue=true) → 重新入队
                                                              ↓
消息到达(Tag=2)← ← ← ← ← ← ← ← ← ← ← ← ← ← ← ← ← ← ← 
       ↑
       Tag=2(新消息)

3.3 代码示例

java 复制代码
@RabbitListener(queues = "test-queue")
public void onMessage(Message message, Channel channel) throws IOException {
    long deliveryTag = message.getMessageProperties().getDeliveryTag();
    System.out.println("当前 Tag: " + deliveryTag);
    
    try {
        // 业务处理...
        channel.basicAck(deliveryTag, false);
    } catch (Exception e) {
        // 重新入队:Tag 会增加(变成新消息)
        channel.basicNack(deliveryTag, false, true);  // requeue=true
    }
}

3.4 Manual 模式三种响应方式

方法 requeue 参数 Tag 变化 说明
basicAck - 消息删除 确认消费
basicNack(requeue=true) true Tag +1 重新入队,变成新消息
basicNack(requeue=false) false 消息删除 丢弃或进入死信队列

四、Tag 变化对比

4.1 完整对比表

场景 Auto 模式 Manual 模式(入队)
首次消费 Tag=1 Tag=1
第1次重试 Tag=1(不变) Tag=2(+1)
第2次重试 Tag=1(不变) Tag=3(+1)
第3次重试 Tag=1(不变) Tag=4(+1)
消息本质 同一条消息 每次都是新消息

4.2 流程对比图

Auto 模式(Tag 不变)

复制代码
                    ┌─────────────────────────────────┐
                    │           内部重试               │
                    │    Tag=1 → Tag=1 → Tag=1        │
                    │         (同一条消息)            │
消息(Tag=1)→ 消费 → 失败 → 重试 → 失败 → 重试 → 成功/入队

Manual 模式(Tag 递增)

复制代码
消息(Tag=1)→ 消费 → 失败 → basicNack(requeue=true)
                                    ↓
                            重新入队(新消息)
                                    ↓
消息(Tag=2)→ 消费 → 失败 → basicNack(requeue=true)
                                    ↓
                            重新入队(新消息)
                                    ↓
消息(Tag=3)→ 消费 → 成功 → basicAck

五、为什么 Tag 会变化?

5.1 Auto 模式原理

复制代码
消费者 ← → Spring 内部队列(内存)
          ↓
     失败后内部重试
          ↓
     Tag 不变(同一条消息)

Auto 模式的重试发生在 Spring 内部,消息从未离开过消费者,所以 Tag 保持不变。

5.2 Manual 模式原理

复制代码
消费者 ← → RabbitMQ Broker
          ↓
     basicNack(requeue=true)
          ↓
     消息回到 Broker 队列
          ↓
     重新投递(新消息,新 Tag)

Manual 模式 basicNack(requeue=true) 是将消息重新放回 Broker,RabbitMQ 会将其视为新消息,分配新的 deliveryTag。


六、注意事项

  1. Manual 入队会导致 Tag 递增 :每次 basicNack(requeue=true) 都会产生新 Tag,可能影响依赖 Tag 的业务逻辑。

  2. Auto 重试是内部机制:Spring 内部重试不经过 Broker,Tag 不变,但重试次数有限。

  3. 幂等性:无论哪种模式,都要保证消费逻辑的幂等性。

  4. 死信队列:Manual 不入队时,建议配置死信队列,避免消息丢失。

  5. 性能:Auto 模式性能高于 Manual 模式。

相关推荐
NJCloud12 小时前
MooseFS 分布式存储部署与高可用架构实践
linux·运维·分布式·架构
zcmodeltech12 小时前
钢铁冶金沙盘模型控制系统设计与实现:高炉-连铸-热轧多工序联动方案
分布式·stm32·单片机·嵌入式硬件·交互
肠畔码农17 小时前
深度解密 Redis 分布式锁:从单机原子语义到集群架构博弈
redis·分布式·架构
小张同学a.21 小时前
Hadoop 分布式集群实战 1—— 集群搭建与在线扩容
大数据·hadoop·分布式
小的~~1 天前
面试被问分布式锁,我差点语塞…直到搞懂了Redis、ZooKeeper和etcd的“三国杀”
redis·分布式·面试
武科大许志伟1 天前
从并行进化到分布式进化计算读 A Survey on Distributed Evolutionary Computation
人工智能·分布式·演化计算
国科安芯1 天前
ASL706S:让 MCU 不再“失忆跑飞“的守护芯片
分布式·单片机·嵌入式硬件·安全·fpga开发·架构
阿无,2 天前
RabbitMQ面试题
分布式·rabbitmq
盛世宏博智慧档案2 天前
全国100个分布式机房环境温湿度智能监测系统建设方案
分布式·机房·温湿度
六bring个六2 天前
分布式设备连接对端失败问题分析
分布式·分布式软总线