RabbitMQ 4.0 是一个重要的版本更新,主要包括 AMQP 1.0 支持、流队列(Stream Queues)支、仲裁队列改进,去除经典队列的 v1 版本支持。在性能、安全和管理界面等方面进行了多项优化与改进。
本文将详细介绍 RabbitMQ 4.0 后新增以及改进的四种主要队列类型:
RabbitMQ 的队列本质上是一个 先进先出(FIFO)的消息缓冲区,用于临时存储生产者发送的消息,并由消费者依次消费。
根据生命周期和使用方式,RabbitMQ 队列可以分为以下几类:
类型 | 生命周期 | 是否持久化 |
|---|---|---|
持久队列 | 永久存在,直到被删除 | ✅ 是 |
临时队列 | 只在服务运行期间存在 | ❌ 否 |
自动删除队列 | 当最后一个消费者断开连接后自动删除 | 可配置 |
接下来,我们深入探讨每种队列类型的实现原理和适用场景。
经典队列是 RabbitMQ 中的原始队列类型,它们使用非复制的 FIFO(先进先出)实现。
经典队列有两种实现(v1 和 v2)。这两个版本仅在数据在磁盘上的存储和检索方式上有所不同,但所有功能在两种实现中均可用。
经典队列用例
经典队列无需复制,非常适合对高可用性和数据安全性要求不高的应用。默认队列类型就是经典队列。
⚠️ 注意:全局 QoS 预取、v1 版本实现将在 RabbitMQ 4.0 被移除。
RabbitMQ Quorum Queue 是一种现代队列类型,它基于 Raft 共识算法实现了持久、复制的 FIFO 队列。
RabbitMQ 中的 Quorum 队列旨在实现高可用性和数据安全性。它们在多个节点之间复制数据,以确保即使某些节点发生故障,消息也不会丢失。
仲裁队列用例
Quorum 队列非常适合那些不接受数据丢失的关键应用。它优先考虑容错能力和数据安全,而非 Classic 队列所具备的最低延迟和高级队列功能。
RabbitMQ 中的流队列是一种持久且可复制的数据结构,与传统队列类似,它缓冲来自生产者的消息,供消费者读取。流队列有两点不同:
Streams 的底层模型是一种不可变的仅追加日志。这意味着写入 Stream 的消息无法被擦除,只能被读取。要在 RabbitMQ 中读取 Stream 中的消息,需要一个或多个消费者订阅该 Stream,并根据需要多次读取同一条消息。
❌ 不支持:
RabbitMQ 通过 MQTT 插件支持 MQTT 协议。默认情况下,MQTT 插件会创建经典队列,也可以配置为创建仲裁队列。
这些传统队列将数据写入磁盘,有时会跨节点复制数据,这可能会导致消息流瓶颈。在某些 MQTT 场景中,要求只需将消息发送给在线订阅者,而无需持久化和/或复制的开销。
这就引出了一个问题:我们如何才能消除这个瓶颈——我们能不能完全不使用队列?这正是 RabbitMQ 3.12 中引入 MQTT QoS 0 队列类型的原因。
与经典队列、仲裁队列和流不同,MQTT QoS 0 队列类型充当“伪”队列,这反而消除了底层队列进程。换句话说,它不作为单独的 Erlang 进程运行,也不将消息存储在磁盘上。相反,它使用订阅客户端的连接进程邮箱。
这意味着消息将直接发送到订阅客户端的 MQTT 连接进程,绕过传统的队列机制,确保立即送达任何“在线”的 MQTT 订阅者。这种方法显著降低了延迟和资源占用。
功能/特性 | 经典队列 | 仲裁队列 | 流队列 | MQTT QoS 0 队列 |
|---|---|---|---|---|
是否持久化 | 可选 | ✅ 默认持久化 | ✅ 默认持久化 | ❌ 不持久化 |
是否复制 | ❌(需镜像) | ✅ Raft 复制 | ✅ 分布式复制 | ❌ |
是否支持重放 | ❌ | ❌ | ✅ 支持多次读取 | ❌ |
是否支持 TTL | ✅ | ❌ | ❌ | ❌ |
是否支持优先级 | ✅ | ❌ | ❌ | ❌ |
吞吐量 | 中等 | 中等 | ✅ 高吞吐 | ✅ 极高(无持久) |
适用场景 | 微服务通信、后台任务 | 金融交易、关键系统 | 实时日志、事件溯源 | IoT 广播、低延迟推送 |
如何选择合适的队列类型?
你的需求是? | 推荐队列类型 |
|---|---|
快速部署、简单易用 | ✅ 经典队列 |
高可用、强一致性 | ✅ 仲裁队列 |
高吞吐、支持消息重放 | ✅ 流队列 |
MQTT 场景、低延迟、无需持久化 | ✅ MQTT QoS 0 队列 |
大规模广播、IoT 场景 | ✅ MQTT QoS 0 队列 |
构建事件溯源、实时分析平台 | ✅ 流队列 |
对数据一致性要求极高 | ✅ 仲裁队列 |
不需要队列持久化、追求极致性能 | ✅ MQTT QoS 0 队列 |