升级 RabbitMQ
升级策略
RabbitMQ 有三种主要的升级策略。下面你会找到所有策略的简要概述。每种策略都有一个专门的页面,其中包含更详细的信息。
滚动(就地)升级
建议使用此升级策略
滚动升级(也称为就地升级)是一种逐个升级节点的过程。有关更多详细信息,请参阅滚动升级指南页面,但以下是主要步骤
- 调查当前版本和目标版本是否具有滚动升级路径
- 检查版本可升级性
- 检查Erlang 版本要求
- 查看发行说明
- 验证是否所有稳定的功能标志都已启用
- 检查节点或集群是否处于良好状态以便升级
- 没有警报生效
- 没有正在进行的队列或流副本同步操作
- 系统在其他方面处于合理的负载之下
- 对于每个节点
- 停止节点
- 升级 RabbitMQ 以及(如果适用)Erlang
- 启动节点
- 观察监控和健康检查数据,以评估升级后的节点和集群的健康状况和恢复情况
- 所有节点都升级后,启用新版本中引入的稳定功能标志
蓝绿部署
此升级策略是最安全的选择。对于因任何原因滚动升级不可行或额外安全特别重要的环境,建议使用此策略
蓝绿部署策略的优点是以暂时增加基础设施占用空间为代价,使升级过程更安全。安全方面来自于操作员可以通过将应用程序切换回旧集群来中止升级的事实。
蓝绿升级通常涉及由部署工具执行或由操作员手动执行的以下步骤。有关这些步骤的更多详细信息,请参阅蓝绿部署指南
- 部署具有所需版本的新集群
- 在新旧集群之间同步元数据(除非应用程序可以声明自己的元数据)
- 设置联邦
- 将消费者切换到新集群
- 耗尽消息
- 将发布者切换到新集群
- 停用旧集群
如果可以接受一些停机时间,则还有一种简化的蓝绿策略
- 部署具有目标版本的新集群
- 停止应用程序
- 在新旧集群之间同步元数据
- 将所有消息从旧集群移动到新集群(例如,使用Shovel)
- 重新配置应用程序以使用新集群
- 启动发布者和消费者
先扩展再收缩升级
此升级策略更改副本标识,可能导致节点之间大量不必要的数据传输,并且只有采取重要预防措施才是安全的。因此,强烈建议不要使用。
先扩展再收缩升级通常涉及以下步骤。考虑一个包含节点 A、B 和 C 的三节点集群
- 调查当前版本和目标版本是否可以集群在一起
- 检查版本可升级性;如果不支持旧版本和新版本之间的滚动升级,则也意味着这两个版本不能在单个集群中共存
- 检查Erlang 版本要求
- 查看发行说明
- 向集群添加一个新节点,节点 D,以便节点 D 能够加入集群)
- 在新节点上放置每个仲裁队列和每个流的新副本
- 检查节点或集群是否处于良好状态
- 没有警报生效
- 没有正在进行的队列或流副本同步操作
- 系统在其他方面处于合理的负载之下
- 使用
rabbitmqctl forget_cluster_node
从集群中删除节点 A - 对其余节点重复上述步骤;在 3 节点集群示例中,集群现在应由节点 D、E 和 F 组成
- 启用新版本中引入的稳定功能标志
可以一次添加和删除多个节点。
RabbitMQ 版本可升级性
你只能从 RabbitMQ 3.13.x 升级到 RabbitMQ 4.0。
不要忘记在升级到 RabbitMQ 4.0 之前,仍然在 3.13 版本时启用所有稳定的功能标志,否则升级将失败。
如果你的版本还不是 RabbitMQ 3.13,请参考下表以了解你的升级路径。
发行系列可升级性
以下显示了支持的升级路径。
从 | 到 | 注释 |
---|---|---|
3.13.x | 4.0.x | 必须在升级之前启用所有稳定的功能标志 |
3.12.x | 3.13.x | |
3.11.18 | 3.12.x | 必须在升级之前启用所有功能标志 |
3.10.x | 3.11.x | 必须在升级之前启用所有功能标志 |
3.9.x | 3.10.x | |
3.8.x | 3.9.x | |
3.7.18 | 3.8.x |
RabbitMQ 3.13 包括对 Khepri 的实验性支持。但是,从那时起必须引入重大更改,导致 3.13 和 4.0 中的 Khepri 支持之间不兼容。因此,启用了 Khepri 的 RabbitMQ 3.13 无法升级到 4.0。蓝绿部署仍然可以在这种情况下使用,因为从技术上讲,它不是升级,而是迁移到全新的集群。
Erlang 版本要求
请参阅Erlang 版本要求指南,以了解给定 RabbitMQ 版本的最低要求和最大支持的 Erlang 版本。
通常建议使用目标 RabbitMQ 版本支持的最新 Erlang 版本。
我们建议你将 Erlang 与 RabbitMQ 一起升级。
版本之间的插件兼容性
RabbitMQ 发行版中包含的插件保证与它们发行的版本兼容。如果使用社区插件,则需要单独验证它们。
管理插件升级
RabbitMQ 管理插件附带一个在浏览器中运行的 Web 应用程序。
升级集群后,强烈建议清除用于访问管理 UI 的域的浏览器缓存、本地存储、会话存储和 Cookie。否则,你可能会遇到 JavaScript 错误。
升级注意事项
系统资源使用量的变化
在升级期间和升级之后,连接和队列将在节点之间以不同的方式进行平衡:当节点关闭时,连接将在剩余节点上重新建立,并且队列 leader 将被重新选举。重要的是要确保你的集群可以在某些(通常是一个)节点关闭以进行升级时维持工作负载。建议在流量低峰时段执行升级。
此外,不同版本的 RabbitMQ 可能具有不同的资源使用率。在升级之前应考虑到这一点:确保有足够的容量来运行新版本的工作负载。始终查阅当前部署版本和目标版本之间的所有版本的发行说明,以了解可能影响你的工作负载和资源使用率的更改。
升级单节点安装
与升级多节点集群相比,升级单节点安装没有根本的区别。
升级开发环境
单节点部署通常是本地开发或测试环境。在这种情况下,如果存储在 RabbitMQ 中的消息不重要,则可以更轻松地直接删除数据目录中的所有内容,然后启动新版本的新节点。实际上,这不再是升级,而是全新安装新版本。
请注意,此过程将删除 RabbitMQ 中的所有数据(定义和消息),但这在开发/测试环境中通常不是问题。可以使用导出/导入来保留定义。这种方法的好处是,你可以轻松地从任何版本跳转到任何其他版本,而无需担心兼容性和功能标志。
降级
RabbitMQ 不正式支持降级 - 它们未经测试,不应依赖。想要额外安全的用户可以使用蓝绿部署方法,该方法允许切换回旧环境。
话虽如此,降级在某些版本之间在技术上是可行的,特别是当它们仅相差一个补丁版本时。但是,这不能保证:曾经有补丁版本甚至无法降级到紧邻的前一个补丁版本。
备份
强烈建议在升级前备份节点的数据目录。
何时重启节点
多个组件和功能取决于节点仲裁的可用性。在最常见的 3 节点集群情况下,这意味着在升级期间应始终有两个节点可用。
RabbitMQ 提供了一个健康检查命令,如果目标节点上的任何仲裁队列、流队列或其他内部组件失去仲裁,则该命令将失败,如果该节点要关闭
- bash
- PowerShell
# exits with a non-zero code if any of the internal components, quorum queues or stream queues
# will lose online quorum should the target node be shut down;
# additionally, it will print which components and/or queues are affected
rabbitmq-diagnostics check_if_node_is_quorum_critical
# exits with a non-zero code if any of the internal components, quorum queues or stream queues
# will lose online quorum should the target node be shut down;
# additionally, it will print which components and/or queues are affected
rabbitmq-diagnostics.bat check_if_node_is_quorum_critical
例如,考虑一个包含节点 A、B 和 C 的三节点集群以及一些仲裁队列。如果节点 B 当前已关闭,则如果针对节点 A 或 C 执行此检查,则检查将失败,因为如果 A 或 C 关闭,则将只有一个节点在运行(因此,将没有仲裁)。当节点 B 重新联机时,相同的检查将成功。
在自动化升级过程时,你可以使用 rabbitmq-upgrade await_online_quorum_plus_one
命令来阻止节点关闭过程,直到有足够的节点运行以维持仲裁。请注意,某些部署选项已经包含此检查 - 例如,当使用 Cluster Operator 在 Kubernetes 上运行 RabbitMQ 时,这已经是 preStop
钩子的一部分。
重新平衡队列 Leader
如果使用滚动升级或先扩展再收缩升级策略,则升级后队列 leader 将不会在节点之间均匀分布。重新平衡队列和流 leader 有助于将负载分散到所有集群节点。
要重新平衡所有队列和流 leader 副本,请运行
- bash
- PowerShell
rabbitmq-queues rebalance all
rabbitmq-queues.bat rebalance all
完全停止升级
无需停止集群中的所有节点即可执行升级。
维护模式
维护模式是一种特殊的节点操作模式,在升级期间可能很有用。该模式由操作员使用下面介绍的一系列新的 CLI 命令显式打开和关闭。
当节点处于维护模式时,它将不可用于服务客户端流量,并将尝试尽可能实际和安全地转移其尽可能多的职责。
目前,这涉及以下步骤
- 暂停所有客户端连接侦听器(将不接受新的客户端连接)
- 关闭所有现有客户端连接:应用程序应重新连接到其他节点并恢复
- 转移目标节点上托管的所有仲裁队列的主副本,并阻止它们参与随后触发的 Raft 选举
- 将节点标记为维护中
- 此时,节点关闭将是最少中断的,因为节点已经转移了其大部分职责
无论队列类型以及队列类型是否支持复制,都不会考虑将处于维护模式的节点用于新的主队列副本放置。
此功能预计将根据 RabbitMQ 操作员、用户和 RabbitMQ 核心团队自身的使用经验的反馈而发展。
处于维护模式的节点预计将在短时间内(例如,5-30 分钟)关闭、升级或重新配置并重新启动。节点不应永久或长时间在此模式下运行。
启用维护模式
要将节点置于维护模式,请使用 rabbitmq-upgrade drain
- bash
- PowerShell
rabbitmq-upgrade drain
rabbitmq-upgrade.bat drain
禁用维护模式
重新启动会自动使节点退出维护模式。
可以使用 rabbitmq-upgrade revive
将处于维护模式的节点恢复,即使其恢复到常规操作状态
- bash
- PowerShell
rabbitmq-upgrade revive
rabbitmq-upgrade.bat revive
该命令的存在是为了回滚(在可能的范围内)drain
命令的效果。仅当你确定无法按计划重新启动节点时,才需要运行此命令。
在重新启动/升级节点后,无需恢复节点,因为重新启动会自动使节点退出维护模式。
检查维护状态
你可以通过运行 rabbitmqctl cluster_status
来检查集群中的任何节点是否处于维护模式。你还可以通过运行 rabbitmqctl status
来检查特定节点的状态。
在应用程序中处理节点重启
为了减少或消除停机时间,应用程序(生产者和消费者)应能够应对服务器发起的连接关闭。一些客户端库提供自动连接恢复来帮助解决此问题
在大多数客户端库中,有一种方法可以响应连接关闭,例如
许多应用程序的恢复过程都遵循相同的步骤
- 重新连接
- 重新打开通道
- 恢复通道设置(例如,
basic.qos
设置,发布者确认) - 恢复拓扑
拓扑恢复包括以下操作,对每个通道执行
- 重新声明应用程序声明的交换机
- 重新声明队列
- 恢复绑定(队列和交换机到交换机绑定)
- 恢复消费者
此算法涵盖了大多数用例,并且是上述自动恢复功能实现的内容。
在滚动升级期间,当节点停止时,连接到此节点的客户端将使用服务器发送的 connection.close
方法断开连接,并且应重新连接到不同的节点。这可以通过在集群前面使用负载均衡器或代理,或者如果客户端库支持此功能,则指定多个服务器主机来实现。
许多客户端库都支持主机列表,例如