RabbitMQ基础知识
1. RabbitMQ是什么
RabbitMQ 本质上是一个 消息代理 / 消息中间件。生产者把消息发给 RabbitMQ,RabbitMQ 负责路由、存储,再把消息投递给消费者。
Producer -> Exchange -> Queue -> Consumer。RabbitMQ 官方文档明确说明,发布发生在 exchange 上,exchange 负责把消息路由到队列、流或其他 exchange,而消费者是从 queue 消费消息
2. RabbitMQ能干什么
1.1 系统解耦
一个业务动作发生后,不想把所有后续逻辑都同步写死在主流程里,比如“订单创建后还要发短信、写日志、扣库存、推送通知”。这时主系统只需要发一个消息,后面的系统各自消费。RabbitMQ 官方教程把这种消息模式拆成了 work queues、publish/subscribe、routing、topics、RPC 等经典模型。
1.2 异步处理
有些逻辑耗时长,但不适合阻塞用户请求,比如发邮件、图片处理、报表生成、清算任务。RabbitMQ 的 work queue 模型本质上就是“把任务放到队列里,由后台 worker 慢慢处理”。
1.3 流量削峰
高峰期系统扛不住瞬时流量时,可以先把请求放进队列,消费者按自己的处理能力去消费。但我也要记住:MQ 是缓冲区,不是无限容量的垃圾桶。RabbitMQ 提供 TTL、队列长度限制、死信等机制,本质就是为了控制消息堆积和转移。
第一部分:入门层
3. RabbitMQ 里的核心角色
3.1 Producer
生产者,负责发送消息。发布动作发生在 channel 上,目标是某个 exchange。
3.2 Consumer
消费者,负责从队列消费消息。RabbitMQ 文档把 consumer 视作一种“订阅关系”,注册之后 broker 会把消息推给它。
3.3 Queue
队列,RabbitMQ 中真正存放消息的地方。很多人会误以为消息是存到 exchange 里的,实际上不是,exchange 负责路由,queue 才负责存储和等待消费。
3.4 Exchange
交换机,接收生产者发布的消息,并根据类型和绑定关系把消息路由出去。RabbitMQ 官方对 exchange 的定义非常直接:它负责把流经它的消息路由到一个或多个队列、流或其他 exchange。
3.5 Binding
绑定,本质是 exchange 和 queue 之间的关系配置。消息能不能从 exchange 进到某个 queue,要看有没有合适的 binding。
3.6 Routing Key
路由键。生产者发消息时会带一个 routing key,exchange 会结合 binding 的规则来决定消息怎么走。不同 exchange 类型对 routing key 的使用方式不同。
4. 一句话理解 RabbitMQ 消息流
生产者不是把消息直接发给队列,而是发给交换机;交换机再决定消息进入哪个队列;消费者最后从队列取消息。 这就是 RabbitMQ 最核心的思维模型。
5. 四种最核心的 Exchange
5.1 direct
特点:精确匹配 routing key。
适用:明确分类分发,比如 order.create 给 A 队列,order.pay 给 B 队列。
5.2 fanout
特点:广播,忽略 routing key。
适用:一个消息要发给多个下游,比如用户注册后同时通知积分系统、优惠券系统、埋点系统。
5.3 topic
特点:按模式匹配 routing key,通常是点分词的形式,例如 order.created、order.paid。
常见通配:
*:匹配一个单词#:匹配零个或多个单词
适用:事件驱动、多条件订阅。
5.4 headers
特点:根据消息头匹配,而不是 routing key。
结论:存在,但实际业务里通常没有 direct、fanout、topic 常用。
6. 消息模式
6.1 简单队列
一个生产者,一个消费者。
6.2 Work Queue
多个消费者消费同一个队列,每条消息只会被其中一个 worker 处理。
适合异步任务处理。
6.3 Publish / Subscribe
一个消息广播给多个消费者。
常配 fanout exchange。
6.4 Routing
按消息类型把消息路由给不同消费者。
常配 direct exchange。
6.5 Topics
按模式灵活订阅。
常配 topic exchange,是项目里最常见的进阶模式之一
6.6 RPC
RabbitMQ 也支持 RPC 风格通信
第二部分:核心理解层
7. Queue 要记住的几个属性
7.1 durable
表示队列定义是否持久化。
注意:durable 只说明队列元数据是否在 broker 重启后保留,不等于消息一定不丢。 官方文档明确说,真要考虑持久化,除了 durable queue,还要让发布者把消息标记为持久消息。
7.2 exclusive
独占队列,通常只给声明它的连接用,并且连接断开后队列会删除。
更适合临时会话场景,不适合核心业务主队列。
7.3 auto-delete
当最后一个消费者取消订阅后,队列会自动删除。
适合临时订阅,不适合订单、支付这种核心业务数据链路。
7.4 queue type
RabbitMQ 现在最重要的队列类型要重点记两个:
- classic queue:传统队列类型。
- quorum queue:基于 Raft 的复制型、高可用队列。官方明确建议,当需要复制且高可用的队列时,quorum queue 应视作默认选择。
8. classic queue 和 quorum queue 怎么选
8.1 classic queue
这是传统默认队列类型,支持独占、TTL、长度限制、优先级、消费者优先级等特性。
8.2 quorum queue
这是现代复制型队列,实现基于 Raft,目标是更好的数据安全和高可用。官方文档明确建议:在需要 replicated / highly available queue 的场景下,quorum queue 应该作为默认选择。
8.3 一个必须记住的版本变化
RabbitMQ 官方已经明确说明,classic mirrored queues 这类老的镜像队列方案在 RabbitMQ 4.0 起已经移除,新项目不要再按旧文章的镜像队列方案设计高可用了。
9. 连接、信道、虚拟主机
9.1 Connection
客户端和 RabbitMQ 节点之间的 TCP 连接。连接通常应该是长连接。消费者更常见的方式是注册订阅,让 broker 主动推消息,而不是不断轮询。
9.2 Channel
信道,是连接上的轻量级逻辑通道。发布、消费、声明交换机和队列这些动作一般都发生在 channel 上。RabbitMQ 也提醒要关注 channel 数量,因为 channel 泄漏和频繁开关都会消耗资源。
9.3 Virtual Host
vhost 可以理解成 RabbitMQ 内部的逻辑隔离空间。交换机、队列、绑定、权限等都属于某个 virtual host。RabbitMQ 官方明确说 vhost 的目标是 逻辑隔离,不是物理资源完全隔离。
第三部分:可靠性层
10. ack 和 confirm 是 RabbitMQ 里最容易混淆的一组概念
这两个必须分清:
10.1 consumer acknowledgement(ACK)
这是 消费者 -> RabbitMQ 的确认。
意思是:这条消息我已经处理完成了。
10.2 publisher confirm
这是 RabbitMQ -> 生产者 的确认。
意思是:这条消息 broker 已经成功接收并接管。官方文档明确说,publisher confirms 是 broker 给 publisher 的一种确认机制。
10.3 最简记忆法
- ack:消费确认—消费者告诉 broker,我处理完了
- confirm:发布确认—告诉生产者,我收到了
11. 为什么手动 ack 很重要
如果消费者拿到消息后立刻 ack,然后再去执行业务,一旦业务失败,消息就已经被 RabbitMQ 当成“处理完成”,这就是逻辑上的丢消息。
所以正确顺序应该是:
收到消息 -> 执行业务 -> 业务成功 -> ack。RabbitMQ 官方文档说明,ack 的目的就是让 broker 知道这次 delivery 已被成功处理。
12. RabbitMQ 的可靠性我应该怎么理解
我把它拆成三段:
12.1 生产者到 Broker
靠 publisher confirms。生产者要知道消息是否被 broker 成功接收。
12.2 Broker 内部存储
靠 durable queue + 持久消息 + 合适的队列类型。如果要更强的数据安全和复制能力,优先看 quorum queue。
12.3 Broker 到消费者
靠 手动 ack。消费者没 ack 就挂了,消息会重新投递。RabbitMQ 的可靠性文档也明确指出,网络故障、应用崩溃、连接中断都是常见故障面,客户端通常要结合自动恢复或自己的恢复逻辑去处理。
13. RabbitMQ 不是“绝不重复”,而是更接近“至少一次”
RabbitMQ 的可靠性语义里,消息重复投递是正常现象,不是 bug。比如消费者处理完业务但 ack 没送达,或者消费者挂掉后消息重新入队,都会出现重复消费。RabbitMQ 官方 reliability guide 也明确把网络故障、节点故障、客户端故障和恢复看作需要应对的常态。
所以必须记住一条工程原则:
RabbitMQ 可靠性的真正落点,不只是“尽量不丢”,还包括“接受重复,然后业务做幂等”。 这条虽然是工程总结,但它正符合 RabbitMQ ack / redelivery 的机制。
第四部分:路由失败、过期、死信
14. mandatory 是干什么的
如果消息发布到了 exchange,但 没有任何队列能路由到,那这条消息就叫 unroutable message。RabbitMQ 官方 publishers 文档说明:如果 mandatory=false,这种消息会被丢弃,或者交给 alternate exchange;如果 mandatory=true,则会 return 给 publisher。
所以理解是:
mandatory 解决的是“消息根本没有进任何队列”怎么办。
15. alternate exchange 是干什么的
AE 是 exchange 级别的兜底机制。当消息无法被正常路由时,可以把它转去 alternate exchange。RabbitMQ 官方文档还特别说明,使用 policy 定义 AE 是推荐做法。
所以 AE 可以记成:
“交换机层面的路由失败兜底”。
16. 死信队列 / DLX 是什么
RabbitMQ 官方明确说,DLX 本质上也是一个普通 exchange。一个队列可以配置 dead-letter-exchange 和 dead-letter-routing-key。当消息在队列阶段发生特定情况时,会被 dead-letter 到这个 exchange。
常见触发条件包括:
- 消费者 reject / nack 且
requeue=false - 消息 TTL 到期
- 队列超过长度限制
- quorum queue 里超过 delivery-limit 的消息。
所以要区分:
- mandatory / AE:解决消息“没路由进队列”
- DLX:解决消息“已经在队列里,但后来失败 / 过期 / 超限”。
17. TTL 是什么
RabbitMQ 的 TTL 文档定义得很清楚:TTL 就是消息或队列的存活时间。
17.1 Message TTL
表示消息在队列里最多能保留多久。超过 TTL 的消息会过期、被丢弃,不会再投递给消费者,也不能通过 basic.get 获取。
17.2 Queue TTL
表示一个队列在满足特定条件下能存在多久。
18. RabbitMQ 延迟队列怎么理解
RabbitMQ 官方没有单独说“内置一个通用延迟队列”,但 TTL 和 DLX 组合起来,确实可以实现最常见的延迟任务模式:
消息先进入设置 TTL 的队列 -> 到期后 dead-letter -> 转发到真正消费队列。 因为 RabbitMQ 官方明确说明,消息 TTL 到期是 dead-letter 的触发条件之一。
这里把它记成:
TTL + DLX = 常见延迟任务实现方案。
第五部分:消费性能与顺序性
19. prefetch 是什么
RabbitMQ 官方把 prefetch 定义为:限制消费者在 ack 之前,最多可以保留多少条未确认消息。AMQP 0-9-1 里是通过 basic.qos 来控制的。
19.1 prefetch=1
一个消费者一次只拿一条,处理完再拿下一条。
优点是更公平。缺点通常是吞吐偏低。
19.2 prefetch 较大
可以提升吞吐,但如果某个消费者慢,就会有更多未 ack 消息压在它手里。
19.3 对 prefetch 的理解
它不是越大越好,而是在平衡:
吞吐、内存占用、消费公平性。
20. RabbitMQ 的顺序性怎么记
RabbitMQ 官方 broker semantics 文档明确给了顺序保证的条件:同一个 channel 发布,经过同一个 exchange、同一个 queue,再通过同一个出站 channel 投递,消息会按发送顺序被接收。
但 RabbitMQ 也明确提醒,下面这些因素会改变消费者观察到的顺序:
- competing consumers(多个消费者并发消费)
- requeue / redelivery(消息重新放回队列,这条消息再被重新投递出去)
- priority queue(优先级队列)
- 某些队列特性。
所以最准确的说法不是“RabbitMQ 保证全局有序”,而是:
RabbitMQ 只在特定条件下能保持顺序,一旦引入并发消费、优先级、重回队列,业务观察到的顺序就可能变化。
21. 幂等为什么必须做
因为 RabbitMQ 的可靠投递机制决定了消息可能重投。只要消息可能重投,消费者就必须能保证“同一条消息重复处理不会把业务搞错”。
RabbitMQ 官方 reliability 文档把网络、客户端、节点等故障视作正常场景,这些故障都会引发重新投递和恢复问题。
所以结论是:
只要用了 RabbitMQ 的手动 ack 和重试思路,就要默认会有重复消费,业务必须做幂等。
第六部分:配置与治理层
22. policy 很重要,很多动态配置应该优先用 policy
RabbitMQ 官方 policies 文档明确说,policy 是一套声明式机制,用来给一组队列、交换机、流配置可在运行时变化的参数。DLX 文档也特别提醒:不推荐把这些参数硬编码成 x-arguments,因为那样更新要改应用并重部署;policy 可以随时调整。
所以记成一句:
能用 policy 管的运行时属性,尽量别写死在业务代码里。
23. 监控和排障不是可选项
RabbitMQ 官方 troubleshooting 文档明确把监控、健康检查、日志、连接泄漏、channel 泄漏、内存使用等列为生产排障重点。channels 文档也提醒要监控 open channels、unacked messages、prefetch 等指标。
所以RabbitMQ 不能只“会发会收”,还要知道至少要关注:
- 队列堆积
- 未确认消息数
- 连接数 / channel 数
- 消费速率
- 死信数量
- 是否有大量 redelivery。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)