RabbitMQ 4.0 新增及改进队列类型深度解析

476 阅读8分钟

RabbitMQ 4.0 是一个重要的版本更新,主要包括 AMQP 1.0 支持、流队列(Stream Queues)支、仲裁队列改进,去除经典队列的 v1 版本支持。在性能、安全和管理界面等方面进行了多项优化与改进。

本文将详细介绍 RabbitMQ 4.0 后新增以及改进的四种主要队列类型:

  • 新增经典队列(Classic Queue)v2 版本
  • 新增仲裁队列(Quorum Queue)
  • 新增流队列(Stream Queue)
  • MQTT QoS 队列插件

📦 什么是 RabbitMQ 队列?

RabbitMQ 的队列本质上是一个 先进先出(FIFO)的消息缓冲区,用于临时存储生产者发送的消息,并由消费者依次消费。

根据生命周期和使用方式,RabbitMQ 队列可以分为以下几类:

  • 持久队列:只要不手动删除,就会一直存在,数据会保存到磁盘上,适合重要数据的存储。​
  • 临时队列:服务运行时存在,服务停止就消失,常用于临时任务处理。​
  • 自动删除队列:当最后一个消费者断开连接后,会自动 “消失”,可根据需求配置。

1️⃣ 经典队列(Classic Queue)

🧩 基本介绍

经典队列是 RabbitMQ 中的原始队列类型,它们使用非复制的 FIFO(先进先出)实现。

经典队列有两种实现(v1 和 v2)。这两个版本仅在数据在磁盘上的存储和检索方式上有所不同,但所有功能在两种实现中均可用。

经典队列用例

经典队列无需复制,非常适合对高可用性和数据安全性要求不高的应用。默认队列类型就是经典队列。

🔧 核心功能

  • 消息和队列生存时间(TTL):可以设置消息在队列中保留多久,或者队列本身的存活时间。​
  • 队列长度限制:避免队列无限增长,占满服务器空间。​
  • 消息和消费者优先级:重要的消息或者消费者可以优先处理。​
  • 死信交换(DLX):处理无法正常消费的 “死信” 消息。​
  • QoS 预取控制:控制消费者一次能获取多少消息,防止消费者过载。​
  • 独占队列:仅供特定连接使用的队列。

⚠️ 注意:全局 QoS 预取、v1 版本实现将在 RabbitMQ 4.0 被移除。官方在4.0 之后默认使用 v2 版本作为经典队列得唯一实现。v2 版本对比 v1 版本,有更高的吞吐量和更低的延迟。

💾 存储实现

  • 使用磁盘存储消息内容(消息体)
  • 每个队列维护一个独立的索引文件,记录消息位置
  • v2 版本引入了“每个队列独立的小消息存储”,提升小消息处理效率

图片

🎯 适用场景

经典队列适合对数据安全和高可用性要求不高的场景。比如一些小型的后台任务分发系统,或者简单的微服务之间的通信,像小商店的订单处理系统,偶尔丢几个订单影响不大,就可以用经典队列。

⚠️ 局限性

  • 自身没有数据复制功能,需要借助镜像队列实现,而镜像队列存在性能和同步问题。​

  • 不支持消息重放,比如消息消费失败后,不能重新获取处理。

2️⃣ 仲裁队列(Quorum Queue)

🧩 基本介绍

仲裁队列基于 Raft 共识算法,实现了数据的持久化和多节点复制,就像给消息找了多个 “备份仓库”,即使部分节点故障,消息也不会丢失。

仲裁队列用例

Quorum 队列非常适合那些不接受数据丢失的关键应用。它优先考虑容错能力和数据安全,而非 Classic 队列所具备的最低延迟和高级队列功能。

🔧 核心功能

  • 数据复制:在多个节点间同步消息,保障高可用性。

  • 持久化存储:数据默认保存到磁盘。​

  • 死信交换:确保消息至少被投递一次。​
  • 毒药消息处理:能识别并处理那些导致消费失败的异常消息。​
  • 故障恢复:具备强大的故障恢复机制。

💾 存储实现

  • 使用预写日志(WAL)记录所有操作
  • 日志条目同时写入内存和磁盘
  • 达到一定大小后写入段文件并压缩
  • 所有节点共享 WAL,保证一致性

图片

🎯 适用场景

在金融交易、订单处理等关键业务系统中,数据绝对不能丢失,仲裁队列就是最佳选择。比如银行转账系统,每一笔转账记录都必须安全可靠。

⚠️ 局限性

  • 不支持 TTL、队列长度限制等高级特性
  • 相比经典队列,延迟略高
  • 不支持非持久或独占队列

3️⃣ 流队列(Stream Queue)

🧩 基本介绍

流队列也是持久且可复制的,但它和传统队列在消息读写方式上有所不同。它的底层就像一本只能追加内容、不能删除内容的日志,消息写入后可以被多次读取。

Streams 的底层模型是一种不可变的仅追加日志。这意味着写入 Stream 的消息无法被擦除,只能被读取。要在 RabbitMQ 中读取 Stream 中的消息,需要一个或多个消费者订阅该 Stream,并根据需要多次读取同一条消息。

🔧 核心功能

  • 持久化和复制:默认开启,保障数据安全。​
  • 非破坏性读取:消息可以被多次消费,不会被删除。​
  • 高吞吐量:能快速处理大规模数据。​
  • 内置惰性行为:消息直接写入磁盘,减少内存压力。​
  • 保留策略:可以按时间或空间设置消息保留规则。

局限性​

  • 不支持 TTL、队列长度限制。​
  • 不支持独占或临时队列。

💾 存储实现

  • 使用固定大小的段文件(Segment Files)存储消息
  • 每个段文件默认大小为 512MB
  • 消息写入磁盘后建立索引,便于快速查找
  • 支持高效的数据压缩和检索

图片

🎯 适用场景

  • 数据分析:比如收集和分析服务器日志、监控系统指标。​
  • 消息回溯:需要重复读取消息进行处理的场景。​
  • 高并发写入和多消费者订阅:像大型电商的促销活动,瞬间大量订单消息涌入,多个系统同时处理。​
  • 构建事件溯源系统:记录系统所有操作事件,方便追溯。

4️⃣ MQTT QoS 队列

🧩 基本介绍

RabbitMQ 通过 MQTT 插件支持 MQTT 协议。在一些 MQTT 场景中,不需要消息持久化和复制,只希望消息快速发给在线订阅者,MQTT QoS 队列就应运而生。它不像传统队列那样作为独立进程运行,也不把消息存到磁盘,而是直接将消息发送到订阅客户端的连接进程邮箱。

🔧 核心功能

  • 极低延迟:消息不经过队列中转,直接送达。​
  • 无需持久化或复制:减少资源消耗。​
  • 适用于扇出广播:一对多的消息发送场景。​
  • 资源占用极低:节省服务器资源。

💾 存储实现

  • 不使用磁盘存储
  • 消息直接发送给在线订阅者的连接邮箱
  • 不创建独立 Erlang 进程

🎯 适用场景

  • 实时数据分析:比如收集和分析服务器日志、监控系统指标。​
  • 消息回溯:需要重复读取消息进行处理的场景。​
  • 高并发写入和多消费者订阅:像大型电商的促销活动,瞬间大量订单消息涌入,多个系统同时处理。​
  • 构建事件溯源系统:记录系统所有操作事件,方便追溯。

⚠️ 局限性

  • 只支持在线订阅者,离线设备收不到消息。​
  • 消息不能持久化,也无法重放。​
  • 仅适用于 MQTT 协议。

📊 四种队列类型对比总结

四种队列类型对比总结

功能 / 特性​经典队列​仲裁队列​流队列​MQTT QoS 0 队列​
是否持久化​可选​默认持久化​默认持久化​不持久化​
是否复制​需镜像​Raft 复制​分布式复制​否​
是否支持重放​否​否​支持多次读取​否​
是否支持 TTL​是​否​否​否​
是否支持优先级​是​否​否​否​
吞吐量​中等​中等​高吞吐​极高(无持久)​
适用场景​微服务通信、后台任务​金融交易、关键系统​实时日志、事件溯源​IoT 广播、低延迟推送​

🧭 总结

如何选择合适的队列类型?​

  • 快速部署、简单易用:经典队列​
  • 高可用、强一致性:仲裁队列​
  • 高吞吐、支持消息重放:流队列​
  • MQTT 场景、低延迟、无需持久化:MQTT QoS 0 队列​
  • 大规模广播、IoT 场景:MQTT QoS 0 队列​
  • 构建事件溯源、实时分析平台:流队列​
  • 对数据一致性要求极高:仲裁队列​
  • 不需要队列持久化、追求极致性能:MQTT QoS 0 队列​

通过了解这四种队列类型的特点和适用场景,我们就能在实际项目中根据需求灵活选择,充分发挥 RabbitMQ 的强大功能。