原生 AMQP 1.0
我们很高兴地宣布,RabbitMQ 4.0 将 AMQP 1.0 作为核心协议提供支持,带来了以下优势:
- 现代化 RabbitMQ,原生支持最新的 AMQP 标准
- 支持更多 AMQP 1.0 功能
- 与 RabbitMQ 3.13 相比,AMQP 1.0 的性能和可扩展性显著提升
- 与其他 AMQP 1.0 消息中间件的互操作性更强
- AMQP 1.0 在 RabbitMQ 4.0 中默认启用
AMQP 历史
高级消息队列协议 (AMQP) 是一个应用层协议,也是一个商业消息传递的标准。
AMQP 最初由摩根大通的 John O’Hara 于 2003 年开发。在他的 2007 年文章 《迈向商品化企业中间件》 中,John O’Hara 阐述了 AMQP 最初的动机。
金融服务行业需要高性能的消息传递中间件(也称为服务总线)。该中间件必须提供持久性以避免消息丢失,并支持存储转发和发布/订阅技术。用例包括自动交易和市场数据事件的缓冲,这些事件的到达率暂时超过后端服务执行的事务处理速率。
一些商业第三方中间件提供商价格过高。一度,华尔街的每家大型投资银行都在构建自己的定制消息传递中间件解决方案。然而,它们反复遇到相同的问题。银行不是软件公司,而消息传递中间件是复杂的软件,难以正确实现。
银行已设法合作创建开放的技术标准,例如:
- 全球银行金融电信协会 (SWIFT)。
- 金融信息交换 (FIX) 协议
- FAST 协议 (FIX 适配流式传输)
- 金融产品标记语言 (FpML)
因此,相同的组织也应该能够为商业消息传递创建开放标准:这就是 AMQP 的诞生原因。
AMQP 规范的要求是:
- 开放标准
- 无专利,允许任何人实现兼容的实现
- 对商业实现有吸引力(否则,AMQP 规范将不会成功)
- 应有多个实现(最终才能符合标准)
- AMQP 软件必须在实际系统中经过验证。中间件是任何系统的关键部分,必须值得信赖。这种信任必须赢得。
- 许多独立公司共同努力,解决了连接系统在一起的相同问题。
快进到现在,AMQP 已被全球绝大多数大型企业跨越所有行业用于关键消息传递基础设施,而 RabbitMQ 是最受欢迎的开源 AMQP 消息中间件。
AMQP 版本
下表显示了不同 AMQP 规范的发布时间。
| AMQP 版本 | 发布日期 |
|---|---|
| 0.8 | 2006 年 6 月 |
| 0.9 | 2006 年 12 月 |
| 0.10 | 2008 年 2 月 |
| 0.9.1 | 2008 年 11 月 |
| 1.0 | 2011 年 10 月 |
John O'Hara 在其 2007 年的文章中写道:
AMQP 工作组正在快速发展该协议,并希望在 2008 年内达到 1.0 版本。
1.0 版本的发布不仅比预期晚了三年,而且协议规范也完全改变了。其结果是,AMQP 1.0 与其发布前的版本(如 AMQP 0.9.1)相比是一个非常不同的协议。
当在对话或文档中提到“AMQP”时,通常会省略版本号,这会引起关于所指协议的大量混淆。由于 RabbitMQ 是最受欢迎的消息中间件,许多网站会引用 AMQP 0.9.1。而其他文档则会引用 AMQP 1.0。
本博客文章的其余部分将省略 AMQP 版本 0.8、0.9 和 0.10,因为它们是已不再使用的旧规范。相反,我们将重点关注 AMQP 版本 0.9.1 和 1.0 之间的差异,这两者在当今的消息中间件中都得到了广泛应用。
总的来说,AMQP 0.9.1 和 AMQP 1.0 之间最大的区别是:

AMQP 0.9.1
客户端将消息发布到一个交换机,该交换机将消息路由到一个队列。队列存储消息,直到它被客户端消费。
更具体地说,发布者将消息发送到一个交换机类型的实例。交换机类型定义了路由算法。AMQP 0.9.1 规范定义了不同的交换机类型,AMQP 0.9.1 中间件必须实现这些类型。
交换机也提供了扩展点。RabbitMQ 提供各种其他交换机类型,并且还可以轻松添加第三方插件到 RabbitMQ。
根据从队列到交换机实例的绑定(包括绑定键)以及消息的路由键(以及可能的其他头部),交换机类型算法决定将消息复制到哪个队列(或哪些队列)。
因此,AMQP 0.9.1 中的模型简单、灵活且强大。如果需要,可以创建复杂的路由拓扑,包括 交换机到交换机的绑定。
交换机、队列和绑定可以由管理员预先声明,也可以通过 HTTP 动态创建,或者更常见的是,直接由客户端应用程序通过 AMQP 0.9.1 创建。具体来说,AMQP 0.9.1 定义了 `exchange.declare`、`queue.declare` 和 `queue.bind` 等协议帧。因此,AMQP 0.9.1 客户端应用程序能够感知服务器拓扑。
RabbitMQ Summit 2023 的演讲 《使用原生 MQTT 和 MQTT 5.0 为数百万客户端提供服务》 解释说,AMQ 0.9.1 模型非常强大,提供了 MQTT 中间件所需的大部分功能。RabbitMQ 使用 AMQ 0.9.1 主题交换机类型将传入 MQTT 数据包中的主题与 MQTT 订阅的主题过滤器进行匹配。
AMQP 1.0
AMQP 1.0 比 AMQP 0.9.1 更通用。AMQP 1.0 不定义服务器模型。事实上,AMQP 1.0 是如此通用,以至于它甚至不强制要求存在中心中间件。AMQP 1.0 定义了对等方之间交换消息。它们通过向 目标 发送消息并从 源 消费消息来实现。
目标和源都包含一个 地址。AMQP 1.0 地址指向的内部对象以及地址如何解析,并未由 AMQP 1.0 规范定义,因为不同的 AMQP 1.0 中间件拥有不同的接收、存储和发送消息的模型。
例如,在实现 AMQP 0.9.1 模型(如 RabbitMQ)的 AMQP 1.0 中间件中,AMQP 1.0 目标地址指向 AMQP 0.9.1 交换机,AMQP 1.0 源地址指向 AMQP 0.9.1 队列。其他 AMQP 1.0 中间件可能会选择一个地址指向一个不可变的日志(流)、一个主题、一些内存数据结构或一个 SQL 数据库。还有另一种 AMQP 1.0 实现可能只是一个客户端库,直接向另一个客户端发送消息,而没有任何中心中间件参与,其中地址可能指向某个操作系统套接字。这取决于 AMQP 1.0 实现,它决定如何解析地址以及如何存储消息。
由于 AMQP 1.0 规范非常通用,因此各种中间件更容易支持 AMQP 1.0,而无需考虑它们用于存储和转发消息的模型。这就是为什么 AMQP 1.0 中间件比 AMQP 0.9.1 中间件更多。
AMQP 0.9.1 vs. AMQP 1.0
下表比较了 AMQP 0.9.1 和 AMQP 1.0。
| AMQP 0.9.1 | AMQP 1.0 | |
|---|---|---|
| 定义服务器模型? | 是:交换机、队列、绑定 | 否:实现决定服务器模型 |
| 标准 | - | ISO/IEC 19464 OASIS |
| 中间件 | RabbitMQ SwiftMQ LavinMQ Apache Qpid Broker-J | RabbitMQ Azure 服务总线 Azure 事件中心 Apache ActiveMQ Apache Qpid Broker-J Apache Qpid C++ Broker IBM MQ Red Hat AMQ SwiftMQ Solace |
| 客户端库 | 大量维护良好的 客户端库和开发工具 | 生态系统较小,但为 .NET 和 Java 提供了维护良好的客户端库 |
| 复杂性 | 中等 | 高 |
| 模块化架构? | 否 | 是,各层是: 1. 类型 2. 传输 3. 消息传递 4. 事务 5. 安全 |
| 可扩展性 | 虽然服务器模型可以通过交换机类型(以及 RabbitMQ 中的队列类型)进行 扩展,并且 RabbitMQ 本身可以通过插件进行扩展,但协议本身的可扩展性非常有限:RabbitMQ 不得不定义自定义 AMQP 0.9.1 协议扩展。 | 专为可扩展性而设计 - 分层架构允许在较低层之上(重新)放置较高层 - 某些帧中的 `properties` 和 `capabilities` 字段允许扩展 - 存在许多 AMQP 1.0 扩展规范。 |
| 类型系统 | 有限且定义不清 | 定义良好的 类型 |
| 流控制 | 简单:例如 消费者预取 | 复杂:链路流控制 和 会话流控制 |
| 特性 | 定义了最重要的商业消息传递功能 | 比 AMQP 0.9.1 更多的功能,包括(但不限于): - 修改结果 - 暂停消费者 - 传输大消息 - 管道化连接建立 - 发送方结算模式 `mixed` - 更好地定义了消息头部部分,并确保基本消息的不可变性 |
AMQP 0.9.1 的普及
乍一看,人们可能会认为较新的 AMQP 1.0 协议版本更好、功能更丰富、性能更高,因此会淘汰并取代旧的 AMQP 0.9.1 实现。然而,事实并非如此。事实上,新的 AMQP 0.9.1 客户端库仍在被创建,例如彭博在去年开源的 C++ 库。令人惊讶的是,即使在 AMQP 1.0 发布多年后,仍然出现了像 LavinMQ 这样的全新 AMQP 0.9.1 中间件实现。
AMQP 0.9.1 相较于 AMQP 1.0 如此流行的原因在于 RabbitMQ 强大的生态系统和社区,以及 AMQP 0.9.1 复杂度较低的事实。简单性通常占优,因为简单性使用户和开发者更容易理解技术,从而导致更多的客户端库被开发和更高的采用率。
如前所述,AMQP 0.9.1 客户端应用程序能够感知交换机、队列和绑定。John O’Hara 在其 2007 年的文章中甚至争辩说,如果没有 AMQP 0.9.1 协议定义模型(交换机、队列和绑定),就无法实现互操作性。
AMQP [0.9.1] 分为两个主要领域:传输模型和队列模型。AMQP [0.9.1] 的不同之处在于它彻底规定了其在队列模型中提供的服务语义;由于应用程序与其中间件有着非常紧密的关系,因此需要对其进行良好定义,否则将无法实现互操作性。
十七年后,我们可以得出结论,他是对的。
鉴于 AMQP 0.9.1 在 2024 年仍然比 AMQP 1.0 更为普及,AMQP 1.0 是否失败了?如上表所示,许多中间件已符合 AMQP 1.0 标准。尽管没有一个中间件实现完整的 AMQP 1.0 规范(由于其复杂性),但任何 AMQP 1.0 客户端都可以与任何这些符合 AMQP 1.0 标准的中间件交换消息。因此,可以说,AMQP 0.9.1 和 AMQP 1.0 都取得了成功。
为什么 RabbitMQ 4.0 会获得 AMQP 1.0 升级?
我们投入资源提供一流的 AMQP 1.0 支持有几个原因:
- 客户需求:商业客户和开源用户都要求更好的 AMQP 1.0 支持。虽然这不是我们投资的主要原因,但有时对话发生在非常高层、非技术层面,潜在客户更愿意将他们的核心消息传递基础设施建立在最新的 AMQP 标准之上,而不是一个预发布版本的 AMQP 规范之上。您可以在 这里 找到一个例子。
- 协议功能:AMQP 1.0 规范拥有定义更完善的类型系统和更多的协议功能,如上表所示。本博客文章仅提供 AMQP 0.9.1 vs. AMQP 1.0 的概述,后续文章将更详细地介绍 AMQP 1.0 的功能。
- 可扩展性:AMQP 1.0 专为可扩展性而设计。协议规范经过了更深入的思考,我们相信可以在未来的 RabbitMQ 版本中利用这种可扩展性。例如,得益于这种可扩展性,RabbitMQ 可以告知 AMQP 1.0 客户端有关队列本地性的信息,从而允许客户端在它们连接的 RabbitMQ 节点上本地发布和消费。
- 性能提升:旧的 RabbitMQ 3.13 插件功能有限,设计不佳,并且由于通过 AMQP 0.9.1 协议进行内部代理而导致速度缓慢。RabbitMQ 4.0 中已修复了大量的 AMQP 1.0 实现错误。
- 互操作性:像 RabbitMQ 这样的开源消息中间件,其核心就是互操作性。AMQP 消息应该能够跨越不同的中间件和组织。由于许多中间件实现了 AMQP 1.0,用户可以更轻松地迁移到(以及从)RabbitMQ。 Alvaro Videla 在他 2023 年 RabbitMQ Summit 的 主题演讲 中演示了另一个互操作性用例,其中消息从 RabbitMQ 移动到 Microsoft Fabric 的实时智能,以使用各种 Azure 云服务分析应用程序消息。
- 多协议消息中间件:RabbitMQ 是市场上最好的多协议消息中间件。它支持 AMQP 0.9.1、MQTT、Streams,并且自 RabbitMQ 4.0 起,原生支持 AMQP 1.0。STOMP 通过插件支持。RabbitMQ 为用户提供了在消息发布和消费方面的完全灵活性:可以使用不同的协议从同一个队列发布和消费消息。RabbitMQ 通过执行 文档中记载的 消息协议转换而表现出色。原生支持 AMQP 1.0 为用户提供了更大的灵活性。
RabbitMQ 3.13 中的 AMQP 1.0
自 AMQP 1.0 于 2011 年发布以来,RabbitMQ 通过插件提供有限的 AMQP 1.0 支持。

RabbitMQ 3.13 及之前的 AMQP 1.0 插件通过 AMQP 0.9.1 在内部代理 AMQP 1.0。换句话说,插件将从客户端接收到的每个 AMQP 1.0 消息转换为 AMQP 0.9.1 消息,然后通过 AMQP 0.9.1 协议将此转换后的消息发送到 RabbitMQ 核心。这种方法存在严重缺点:
- 有限的功能支持: AMQP 1.0 的支持仅限于 AMQP 0.9.1 协议提供的功能子集。
- 性能低下: 每条消息都必须在 AMQP 0.9.1 和 AMQP 1.0 之间进行转换。
- 资源消耗大: 这种方法在内存和 CPU 使用方面非常消耗资源,因为插件中的每个 AMQP 1.0 会话 都包含一个 AMQP 0.9.1 客户端并维护 AMQP 0.9.1 状态。
正如在《使用原生 MQTT 为数百万客户端提供服务》博客文章中所述,MQTT 插件在 RabbitMQ 3.11 之前在概念上工作方式相同:它也通过 AMQP 0.9.1 协议在内部代理。
RabbitMQ 4.0 中的 AMQP 1.0
在 RabbitMQ 4.0 中,原生 AMQP 1.0 支持取代了 AMQP 1.0 插件。

AMQP 1.0 客户端直接将消息发送到交换机(AMQP 1.0 目标),并直接从队列(AMQP 1.0 源)接收消息。换句话说,原生 AMQP 1.0 不再通过 AMQP 0.9.1 **协议**进行代理,而是继续利用简单、灵活且强大的 AMQ 0.9.1 **模型**。这种转变带来了几个好处:
- 增强的功能支持: 支持更多 AMQP 1.0 功能。这反映了 RabbitMQ 3.12 中引入原生 MQTT 如何促进添加更多协议功能,例如 RabbitMQ 3.13 中的 MQTT 5.0。
- 高性能: 原生 AMQP 1.0 提供更高的吞吐量和更低的延迟。
- 资源消耗少: 中间件的内存和 CPU 使用率降低,每个 AMQP 1.0 会话 使用单个 Erlang 进程,而 RabbitMQ 3.13 中则使用 15 个 Erlang 进程。
因此,原生 AMQP 1.0 遵循了原生 MQTT 的成功故事。
淘汰 AMQP 1.0 插件,这在图表中看起来很简单,但实际上需要 12 个月的工程工作。这项广泛的努力是由于几个因素:
- AMQP 1.0 协议的复杂性: AMQP 1.0 是 RabbitMQ 支持的最复杂的协议,比 AMQP 0.9.1 和 MQTT 都更复杂。
- 队列修改: AMQP 1.0 客户端可以直接从每种队列类型消费,这使得需要修改经典队列、仲裁队列和流式实现。
- 滚动升级: 我们支持从 RabbitMQ 3.13 到 4.0 的滚动升级,允许您在不停机的情况下升级 AMQP 1.0 工作负载。
尽管 RabbitMQ 4.0 原生支持 AMQP 1.0,但这并不意味着 RabbitMQ 支持所有 AMQP 1.0 功能。与其他任何 AMQP 1.0 中间件一样,RabbitMQ 的 AMQP 1.0 实现存在 文档记录的限制。
RabbitMQ AMQP 1.0 客户端
我们为 RabbitMQ 开发了两个新的 AMQP 1.0 客户端库:
这些客户端库具有以下特点:
- 轻量级包装器: 它们是轻量级包装器,其中包含围绕现有开源 AMQP 1.0 客户端库构建的 RabbitMQ 特定逻辑。
- 约定俗成的 API: 它们提供了一个简单安全的 API,旨在帮助应用程序开发人员轻松开始通过 AMQP 1.0 发送和接收消息。
- RabbitMQ 模型集成: 它们使应用程序能够通过 AMQP 1.0 管理 RabbitMQ 的 AMQ 0.9.1 模型(例如声明和删除交换机、队列和绑定)。此功能利用了 HTTP over AMQP 1.0 扩展规范。
- 两全其美: 应用程序可以通过动态创建服务器拓扑来保持与中间件的“紧密关系”,同时享受对否则复杂的 AMQP 1.0 协议的简单体验。此外,应用程序可以选择绕过轻量级的 RabbitMQ 特定包装器,直接与底层的 AMQP 1.0 客户端库交互,以访问更高级的 AMQP 1.0 功能。
- 减少网络流量: 在某些场景下,它们可以通过识别给定队列所在的 RabbitMQ 节点来减少集群内部流量,从而允许应用程序从这些节点“本地”发布和消费。
- 可选: 使用这些客户端库并非与 RabbitMQ 通过 AMQP 1.0 交互的必需条件。任何其他 AMQP 1.0 客户端也应该能够与 RabbitMQ 通信。
RabbitMQ 现代化
RabbitMQ 4.0 完成了其现代化历程,该历程始于 2019 年的 RabbitMQ 3.8。这些现代化包括:
- 仲裁队列:使用 Raft 共识算法提供安全、可复制且能抵抗网络分区的队列类型。
- Prometheus 指标和 Grafana 仪表板:提供一流的可观测性集成和 警报。
- RabbitMQ on Kubernetes:允许在任何地方运行 RabbitMQ 的运算符。
- 流:一个不可变的日志,提供消息重放和高消息吞吐量,以及 流协议。
- 经典队列存储版本 2:提供更高的消息吞吐量和更低的内存使用。
- 商业 灾难恢复解决方案:确保在整个数据中心发生故障时保持业务连续性。
- 原生 MQTT 和 MQTT 5.0:将 RabbitMQ 转变为物联网中间件。
- Khepri:使用 Raft 共识算法提供安全、可扩展且能抵抗网络分区的元数据存储。
- 原生 AMQP 1.0: 将 RabbitMQ 的核心协议升级到最新的 AMQP 标准(如本文档所述)。
我们鼓励您尝试并测试 RabbitMQ 4.0 中的 AMQP 1.0,并提供 反馈。您可以使用最新的 rabbitmq:4.0 Docker 镜像。虽然我们鼓励您使用 AMQP 1.0 构建新应用程序,但我们将在 RabbitMQ 4.x 中继续支持和维护 AMQP 0.9.1。
观看我们的 RabbitMQ Summit 2024 关于原生 AMQP 1.0 的演讲,并阅读更多关于 AMQP 1.0 功能和性能基准的 技术博客文章。
