原生 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 年在 JPMorgan 开发。在他的文章 Toward a Commodity Enterprise Middleware (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 0.9.1 等预发布版本相比,AMQP 1.0 是一个非常不同的协议。
当在对话或文档中提到“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 演讲 Serving millions of clients with Native MQTT and 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 0.9.1 代理相比,存在更多 AMQP 1.0 代理的原因。
AMQP 0.9.1 与 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++ 库,该库由 Bloomberg 去年刚刚开源。令人惊讶的是,即使是全新的 AMQP 0.9.1 代理实现(例如 LavinMQ)也是在 AMQP 1.0 发布多年后从头开始开发的。
与 AMQP 1.0 相比,AMQP 0.9.1 如此流行的原因是 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] 的不同寻常之处在于它彻底地指定了其在排队模型中提供的服务的语义;由于应用程序与其中间件有着非常密切的关系,因此需要明确定义这一点,否则无法实现互操作性。
十七年后,我们可以得出结论,他是对的。
鉴于 2024 年 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 和 AMQP 1.0 都已成功。
为什么 RabbitMQ 4.0 获得 AMQP 1.0 升级?
我们投资一流 AMQP 1.0 支持有以下几个原因
- 客户需求:商业客户和开源用户都要求更好的 AMQP 1.0 支持。虽然不是我们投资的主要原因,但有时对话发生在如此高层次的非技术层面,以至于潜在客户更喜欢将其中心消息传递基础设施基于最新的 AMQP 标准,而不是预发布的 AMQP 规范。可以在 此处 找到一个示例。
- 协议功能:AMQP 1.0 规范具有定义更完善的类型系统和更多协议功能,如上表部分所示。这篇博文仅概述了 AMQP 0.9.1 与 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 在他的 RabbitMQ Summit 2023 主题演讲 中演示了另一个互操作性用例,其中消息从 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
自 2011 年 AMQP 1.0 发布以来,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 状态。
正如 Serving Millions of Clients with Native 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 集群内部流量,从而允许应用程序从这些节点“本地”发布和使用。
- 可选:与 RabbitMQ 通过 AMQP 1.0 交互不需要这些客户端库。任何其他 AMQP 1.0 客户端也应该能够与 RabbitMQ 通信。
RabbitMQ 现代化
RabbitMQ 4.0 完成了其现代化之旅,该之旅始于 2019 年的 RabbitMQ 3.8。这些现代化包括
- 仲裁队列:使用 Raft 共识算法提供安全、复制的队列类型,可抵抗网络分区。
- Prometheus 指标和 Grafana 仪表板:提供一流的可观察性集成和 警报。
- Kubernetes 上的 RabbitMQ:在任何地方运行 RabbitMQ 的操作符。
- Streams:不可变的日志,通过 流协议 提供消息重放和高消息吞吐量。
- 经典队列存储版本 2:提供更高的消息吞吐量和更低的内存使用率。
- 商业 灾难恢复解决方案:确保整个数据中心宕机时的业务连续性。
- 原生 MQTT 和 MQTT 5.0:将 RabbitMQ 转型为 IoT 代理。
- 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 功能和性能基准的 博客文章。