公司内部业务需要将RabbitMQ服务从3.6.16版本升级到4.1.1版本,需要梳理每个版本的主要升级内容,同时记录如何使用RabbitMQ4.1.1版本,以及升级过程中的注意事项。
基本信息
- RabbitMQ4.1.1:2025年6月发布
- RabbitMQ3.6.16:2018年6月发布
核心架构与存储系统
- Khepri元数据存储:RabbitMQ 4.0 引入了 Khepri 作为新的元数据存储系统,替代了原有的 Mnesia。Khepri 基于 Raft 共识算法,显著提升了集群元数据的可靠性和管理效率,尤其在大规模集群中表现更稳定。
- 经典队列镜像功能移除:4.0 版本彻底移除了经典队列的镜像功能(已被弃用多年),推荐使用Quorum 队列或 ** 流(Streams)** 实现高可用性。经典队列在 4.0 后变为非复制队列,需通过 Quorum 队列或流确保数据冗余。
- Erlang 版本依赖升级:4.0 及以上版本要求 Erlang 26 或更高版本,而 3.6.16 依赖 Erlang 19-20。新 Erlang 版本带来了更好的并发性能和安全修复。
各版本的主要升级内容
- 3.7版本
- 引入的 Quorum队列 基于 Raft共识算法 ,通过多数派机制保证数据一致性,支持自动故障转移和毒消息处理。
- 3.8版本
- 引入实验性
OAuth2插件
。
- 支持
TLSv1.3(Erlang 23+)
。
- 支持单活跃消费者(Single Active Consumer),确保同一时间仅有一个消费者处理队列消息,提升可用性。
- 4.0版本
- 引入检查点(Checkpoint)机制,显著减少了
Quorum队列
在节点重启时的恢复时间。
- 引入流(Streams),支持持久化、分区和高吞吐量的消息传递,适用于需要长期保留消息或高吞吐量的场景。
- 改进了经典队列的存储引擎(CQV2),减少了大消息存储的磁盘占用,并优化了恢复时间。
- 将AMQP 1.0设为核心协议,其实现效率大幅提升,峰值吞吐量较
3.13.x
版本提升超过两倍。
- 设
TLSv1.3(Erlang 23+)
为默认启用,并改进了TLS配置的灵活性。
- 开始跟踪客户端认证失败次数,并通过Prometheus指标和HTTP API暴露。
- 移除了
cluster_formation.randomized_startup_delay_range
等过时配置,新增khepri相关配置。
- 不再支持
Erlang 21.3
及以下,需更新客户端库(如 pika、amqp-client)。
- 减少了节点启动时间(尤其是插件较多时),启动速度提升20-30%。
- 将AMQP 1.0插件设为内置,无需手动启用。
- 改进了TLS配置选项,支持证书链验证深度为零。
- 4.1.1版本
- 新增
rabbitmq-queues force_checkpoint
,用于强制Quorum队列生成检查点,同时清理磁盘段文件。
- 新增
/api/health/checks/ready-to-serve-clients
,用于检查节点是否在连接数限制内并准备服务。
- 优化了Quorum队列恢复机制,修复了集群形成期间的超时问题,并支持消费者优先级。
- 优化了 OAuth2 插件的作用域变量支持
- 优化了OAuth2插件的作用域变量支持(如x-vhost和sub参数),允许更灵活的权限控制,例如
rabbitmq.write:*
可动态匹配虚拟主机和用户。
- 优化了 Shovel 插件的消息转换逻辑,支持复杂头信息处理。
- 加快了空经典队列在干净关闭后的初始化速度。
- 修复了AMQP 1.0客户端在高负载下的窗口大小负值问题。
- 修复了TLS连接错误日志的缺失问题。
- 修复了经典队列在高并发发布时的存储压缩滞后问题,以及消息路由到多个队列时的罕见异常。
- 修复了流生产者在启用发布过滤时的异常问题。
PHP的使用推荐
依赖选择
特性 |
pecl-amqp(C 扩展) |
php-amqplib(纯 PHP) |
安装方式 |
编译 C 扩展(依赖 rabbitmq-c) |
Composer 安装(无需编译) |
性能 |
高(原生 C 实现) |
较低(PHP 解释执行) |
RabbitMQ 4.x 兼容性 |
不支持新特性(如 Quorum 队列) |
支持(需 v3.x 版本) |
PHP 版本依赖 |
1.9.4 支持 PHP 5.6~7.4 |
v3.x 需 PHP 7.2+ |
代码示例 |
$connection = new AMQPConnection(); |
use PhpAmqpLib\Connection\AMQPStreamConnection; |
版本支持
RabbitMQ 版本 |
推荐客户端(优先) |
推荐版本 |
支持的 PHP 版本 |
核心优势 |
3.6.16 |
php-amqplib |
^2.12 |
5.6+ |
兼容性好,无需编译 |
3.6.16 |
pecl-amqp |
1.9.x |
5.6-7.4 |
性能优于纯 PHP 实现 |
4.1.1 |
php-amqplib |
^3.6 |
7.2+ |
支持所有新特性,维护活跃 |
4.1.1 |
pecl-amqp |
^2.0 |
7.4+ |
高性能,适合高并发场景 |
RabbitMQ中的队列类型及特点
在 RabbitMQ 4.1.1 中,Classic Queue(经典队列)、Quorum Queue(仲裁队列)和Stream(流)是三种不同类型的消息存储和处理机制,它们在设计目标、可靠性、性能和适用场景上存在显著差异。
Classic Queue(经典队列)
核心特点
- 存储机制:消息存储在单个节点上,支持镜像复制(Mirroring)到多个节点,但镜像机制已被弃用。
- 一致性保证:弱一致性,镜像队列通过异步复制实现高可用,主节点故障时可能丢失未同步的消息。
- 性能:低延迟,单节点处理效率高,但扩展能力有限。
- 实现原理:基于 Mnesia 数据库(RabbitMQ 4.0 前的元数据存储系统),消息存储在内存或磁盘(取决于配置)。
优点
- 低延迟:单节点处理,无需共识协议,适合对延迟敏感的场景。
- 兼容性好:支持所有 RabbitMQ 版本,包括 3.6.x 及更早版本。
- 简单易用:配置简单,无需复杂参数。
缺点
- 可靠性低:镜像队列异步复制,主节点故障可能导致消息丢失。
- 维护复杂:镜像队列管理复杂,故障恢复时间长。
- 扩展性差:性能受限于单个节点,无法水平扩展。
适用场景
- 非关键业务(如日志收集、通知推送)。
- 对消息丢失容忍度高的场景。
- 历史遗留系统,无法升级到新队列类型。
Quorum Queue(仲裁队列)
核心特点
- 存储机制:基于 Raft 共识算法,消息同步复制到多数节点(通常 3-5 个),确保强一致性。
- 一致性保证:强一致性,通过多数派确认(Quorum)确保消息不丢失。
- 性能:中等延迟(比 Classic 高 20-30%),吞吐量取决于集群规模。
- 实现原理:基于 Khepri 元数据存储系统(RabbitMQ 4.0 引入),支持自动故障转移和毒消息处理。
优点
- 高可靠性:强一致性保证,主节点故障时不会丢失消息。
- 自动恢复:支持自动故障转移,无需人工干预。
- 简化运维:无需手动管理镜像,降低运维复杂度。
缺点
- 更高延迟:需等待多数节点确认,延迟比 Classic 高。
- 资源消耗大:至少需要 3 个节点,资源利用率低于 Classic。
- 兼容性限制:仅支持 RabbitMQ 3.8+,客户端需支持扩展参数。
适用场景
- 关键业务(如订单处理、支付系统)。
- 对消息可靠性要求极高的场景。
- 需要自动故障转移和简化运维的场景。
Stream(流)
核心特点
- 存储机制:基于 Apache Kafka 类似的日志结构化存储,支持持久化、分区和高吞吐量。
- 一致性保证:强一致性,通过 Raft 算法确保消息顺序和持久性。
- 性能:极高吞吐量(百万级 TPS),低延迟(亚毫秒级)。
- 实现原理:将消息追加到不可变日志文件,支持多消费者并行消费。
优点
- 超高吞吐量:适合大数据、实时分析等高流量场景。
- 长期存储:支持消息按时间或大小保留,无需手动清理。
- 分区扩展:通过分区支持水平扩展,突破单机性能限制。
缺点
- 高资源消耗:需要更多磁盘空间和内存。
- API 限制:仅支持特定客户端 API,兼容性不如 Classic 和 Quorum。
- 复杂性高:需要理解分区、偏移量等概念,学习成本较高。
适用场景
- 高吞吐量数据流(如实时监控、IoT 数据采集)。
- 需要长期保留历史消息的场景。
- 需要分区并行处理的场景。
对比总结
特性 |
Classic Queue |
Quorum Queue |
Stream |
一致性 |
弱一致性(异步复制) |
强一致性(Raft 共识) |
强一致性(Raft 共识) |
可靠性 |
中等(可能丢失消息) |
高(多数派确认) |
高(持久化日志) |
性能 |
低延迟,中等吞吐量 |
中等延迟,中等吞吐量 |
高吞吐量,低延迟 |
扩展性 |
单节点瓶颈 |
支持多节点,但受限于共识 |
支持分区水平扩展 |
消息保留 |
基于 ACK 或 TTL |
基于 ACK 或 TTL |
基于时间或大小 |
镜像管理 |
手动配置,复杂 |
自动管理,简单 |
自动管理,支持分区 |
适用场景 |
非关键业务,低延迟 |
关键业务,高可靠性 |
高吞吐量,长期存储 |
选型建议
- 优先使用 Quorum Queue
- 除非对延迟极其敏感(如高频交易),否则推荐使用 Quorum 替代 Classic,尤其是关键业务场景。
- 使用 Stream 的场景
- 当吞吐量需求超过 Quorum 的能力(如每秒百万级消息),或需要长期保留历史数据时,选择 Stream。
- Classic Queue 的保留场景
- 历史遗留系统,无法升级客户端。
- 对延迟要求极高,且能容忍消息丢失的场景。
- 混合部署策略
- 关键业务用 Quorum,非关键业务用 Classic,高吞吐量场景用 Stream。
- 例如:订单系统用 Quorum,日志收集用 Classic,实时监控用 Stream。
PHP示例
使用Quorum Queue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| use PhpAmqpLib\Connection\AMQPStreamConnection; use PhpAmqpLib\Channel\AMQPChannel;
$connection = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest'); $channel = $connection->channel();
$channel->queue_declare( 'my_quorum_queue', // 队列名称 false, // passive true, // durable false, // exclusive false, // auto_delete false, // nowait [ 'x-queue-type' => ['S', 'quorum'] // 关键参数 ] );
|
使用Stream
1 2 3 4 5 6 7 8 9 10 11 12 13
| $channel->queue_declare( 'my_stream', false, true, false, false, false, [ 'x-queue-type' => ['S', 'stream'], // 关键参数 'x-max-length-bytes' => ['I', 1073741824] // 1GB存储限制 ] );
|