在 RabbitMQ 的消费者代码中,Channel 和 tag 参数的存在是为了实现消息确认机制(Acknowledgment)和精细化的消息控制。
Channel 参数
作用
Channel 是 AMQP 协议的核心操作接口,通过它可以直接与 RabbitMQ 交互:
- 手动消息确认:通过
basicAck/basicNack显式告知 RabbitMQ 消息处理结果 - 流量控制:可调用
basicQos限制预取消息数量(防止消费者过载) - 其他高级操作:如消息重发、队列绑定等
如果不传入
Channel,Spring AMQP 会自动使用默认信道,但会失去对信道的直接控制权。
对应原理


生产者的 Channel
- 当生产者调用
rabbitTemplate.convertAndSend()时:
rabbitTemplate.convertAndSend("doctor.queue", jsonMessage);
- Spring AMQP 内部会从 连接池 获取一个
Channel(信道)。 - 该
Channel用于将消息发布到指定队列。 - 发布后自动关闭(如果是非事务模式)或复用。
消费者的 Channel
- 消费者通过
@RabbitListener监听队列时:
@RabbitListener(queues = "doctor.queue")
public void onMessage(String json, Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long tag) {
// 处理逻辑
}
- Spring AMQP 会为每个消费者线程分配一个 独立的
Channel。 - 所有消息的确认(ACK/NACK)必须通过 同一个 Channel 操作(否则会报错)。
tag 参数
作用
@Header(AmqpHeaders.DELIVERY_TAG) 注入的 tag 是消息的唯一标识符:
- 消息指纹:每个投递给消费者的消息都会获得唯一的 delivery tag
- 幂等性设计:通过 tag 可以精确确认/拒绝特定消息
- 必须参数:调用
basicAck/basicNack时必须指定此 tag
Tag 的数值范围仅在当前信道内唯一,不同信道的 tag 可能重复。
对应原理
Tag 的生成
- 当 RabbitMQ 将消息推送给消费者时:
- 服务端会为 每条消息 分配一个唯一的
Delivery Tag(在当前 Channel 内递增)。 - 例如:第一次推送的 Tag=1,第二次 Tag=2,…(不同 Channel 的 Tag 独立计数)。
- 服务端会为 每条消息 分配一个唯一的
Tag 的作用
- 唯一标识消息:消费者通过 Tag 告诉 RabbitMQ 要确认/拒绝哪条消息。
channel.basicAck(tag, false); // 确认当前消息
channel.basicNack(tag, false, true); // 拒绝并重新入队
- 严格顺序性:Tag 在同一个 Channel 内严格递增,确保消息顺序处理。
- RabbitMQ 服务端维护了一个 消息投递状态表,记录每个 Channel 的 Tag 对应哪条消息。
- 当消费者发送 ACK/NACK 时,RabbitMQ 根据 Channel + Tag 组合定位到原始消息。
手动确认模式
手动确认模式的优点:
- 可靠性:只有处理成功的消息才会被确认(
basicAck) - 错误恢复:处理失败时通过
basicNack让消息重新入队 - 业务控制:可以根据业务逻辑决定是否确认(如示例中的
shouldBeProcessed判断)
// 成功处理 - 确认删除
channel.basicAck(tag, false);
// 处理失败 - 拒绝并重新入队
channel.basicNack(tag, false, true);
工作流程










![[electron]预脚本不显示内联script](https://i-blog.csdnimg.cn/direct/db8776b223664dc7836ebf2ac3c85cb9.png)



![浏览器工作原理01 [#]Chrome架构:仅仅打开了1个页面,为什么有4个进程](https://i-blog.csdnimg.cn/img_convert/6a4a97cdbbb3b1ba61cf0f824dfd6c1e.png)


![[学习笔记]使用git rebase做分支差异化同步](https://i-blog.csdnimg.cn/direct/cfc67caffabd42248e2a5b5bc478a796.png)


