[ English | Indonesia | русский ]
RabbitMQ 集群维护¶
RabbitMQ broker 是一个 Erlang 节点的一个或多个逻辑分组,每个节点运行 RabbitMQ 应用程序,并共享用户、虚拟主机、队列、交换器、绑定和运行时参数。节点集合通常被称为 集群。有关 RabbitMQ 集群的更多信息,请参阅 RabbitMQ 集群。
在 OpenStack-Ansible 中,RabbitMQ 集群运行所需的所有数据和状态都复制到所有节点,包括消息队列,从而提供高可用性。RabbitMQ 节点使用域名相互寻址。集群所有成员的主机名必须可以从所有集群节点以及可能使用与 RabbitMQ 相关的 CLI 工具的任何机器解析。在更严格的环境中,也可以使用替代方案。有关该设置的更多详细信息,请参阅 Inet 配置。
创建 RabbitMQ 集群¶
RabbitMQ 集群可以通过两种方式形成
使用
rabbitmqctl手动声明式(配置中的集群节点列表,使用
rabbitmq-autocluster或rabbitmq-clusterer插件)
注意
RabbitMQ broker 可以容忍集群内单个节点的故障。只要它们能够在关闭时访问之前已知的成员,这些节点就可以随意启动和停止。
您可以配置两种类型的节点:磁盘节点和 RAM 节点。最常见的是,您会将节点用作磁盘节点(首选)。而 RAM 节点更多的是用于性能集群的特殊配置。
RabbitMQ 节点和 CLI 工具使用 erlang cookie 来确定它们是否具有通信权限。cookie 是一个字母数字字符串,可以短也可以长,由您决定。
注意
cookie 值是一个共享密钥,应受到保护并保密。
在 *nix 环境中,cookie 的默认位置是 /var/lib/rabbitmq/.erlang.cookie 或 $HOME/.erlang.cookie。
提示
在故障排除时,如果您发现一个节点拒绝加入集群,那么检查 erlang cookie 是否与其它节点匹配绝对值得。当 cookie 配置错误(例如,不相同)时,RabbitMQ 会记录诸如“来自禁止节点的连接尝试”和“无法自动集群”之类的错误。有关更多信息,请参阅 集群。
要形成 RabbitMQ 集群,您首先获取独立的 RabbitMQ broker,然后将这些节点重新配置为集群配置。
使用 3 个节点的示例,您将告诉节点 2 和 3 加入第一个节点的集群。
登录到第 2 个和第 3 个节点并停止 RabbitMQ 应用程序。
加入集群,然后重新启动应用程序
rabbit2$ rabbitmqctl stop_app Stopping node rabbit@rabbit2 ...done. rabbit2$ rabbitmqctl join_cluster rabbit@rabbit1 Clustering node rabbit@rabbit2 with [rabbit@rabbit1] ...done. rabbit2$ rabbitmqctl start_app Starting node rabbit@rabbit2 ...done.
检查 RabbitMQ 集群状态¶
从任何节点运行
rabbitmqctl cluster_status。
您将看到 rabbit1 和 rabbit2 都在像以前一样运行。
区别在于,输出的集群状态部分,现在两个节点都分组在一起了
rabbit1$ rabbitmqctl cluster_status
Cluster status of node rabbit@rabbit1 ...
[{nodes,[{disc,[rabbit@rabbit1,rabbit@rabbit2]}]},
{running_nodes,[rabbit@rabbit2,rabbit@rabbit1]}]
...done.
要将第三个 RabbitMQ 节点添加到集群,请重复上述过程,停止第三个节点上的 RabbitMQ 应用程序。
加入集群,并在第三个节点上重新启动应用程序。
执行
rabbitmq cluster_status以查看所有 3 个节点rabbit1$ rabbitmqctl cluster_status Cluster status of node rabbit@rabbit1 ... [{nodes,[{disc,[rabbit@rabbit1,rabbit@rabbit2,rabbit@rabbit3]}]}, {running_nodes,[rabbit@rabbit3,rabbit@rabbit2,rabbit@rabbit1]}] ...done.
停止并重新启动 RabbitMQ 集群¶
要停止和启动集群,请记住您关闭节点的顺序。您停止的最后一个节点,必须是您启动的第一个节点。该节点是 master。
如果您以错误的顺序启动节点,您可能会遇到一个问题,即它认为当前的 master 不应该成为 master,并丢弃消息以确保在真正的 master 恢复之前,不会排队新的消息。
RabbitMQ 和 Mnesia¶
Mnesia 是一个分布式数据库,RabbitMQ 使用它来存储有关用户、交换器、队列和绑定的信息。但是,消息并未存储在数据库中。
有关 Mnesia 的更多信息,请参阅 Mnesia 概述。
要查看重要 RabbitMQ 文件的位置,请参阅 文件位置。
修复单个节点的已分区 RabbitMQ 集群¶
由于您的环境中的某些原因,您可能会失去集群中的一个节点。在这种情况下,多个 LXC 容器在同一主机上运行 RabbitMQ,并且位于单个 RabbitMQ 集群中。
如果主机仍然显示为集群的一部分,但未运行,请执行
# rabbitmqctl start_app
但是,您可能会注意到应用程序存在一些问题,因为客户端可能正在尝试将消息推送到未响应的节点。为了解决这个问题,请通过执行以下操作从集群中忘记该节点
确保 RabbitMQ 未在节点上运行
# rabbitmqctl stop_app
在 RabbitMQ 第二个节点上,执行
# rabbitmqctl forget_cluster_node rabbit@rabbit1
通过这样做,集群可以有效地继续运行,您可以修复故障节点。
重要提示
在您重新启动节点时要小心,它仍然会认为它是集群的一部分,并且需要您重置该节点。重置后,您应该能够将其重新加入到其它节点,如果需要的话。
rabbit1$ rabbitmqctl start_app
Starting node rabbit@rabbit1 ...
Error: inconsistent_cluster: Node rabbit@rabbit1 thinks it's clustered
with node rabbit@rabbit2, but rabbit@rabbit2 disagrees
rabbit1$ rabbitmqctl reset
Resetting node rabbit@rabbit1 ...done.
rabbit1$ rabbitmqctl start_app
Starting node rabbit@mcnulty ...
...done.
修复多节点集群的已分区 RabbitMQ 集群¶
与存在于单个节点集群中的多节点集群相同的概念适用。唯一的区别是,各个节点实际上将运行在不同的主机上。在处理多节点集群时需要记住的关键事项是
当整个集群被关闭时,最后一个关闭的节点必须是第一个启动的节点。如果这样不发生,节点将等待 30 秒,等待最后一个磁盘节点恢复在线,然后失败。
如果最后一个关闭的节点无法启动,可以使用 forget_cluster_node 命令将其从集群中删除。
如果所有集群节点以同时且不受控制的方式停止(例如,停电),您可能会遇到所有节点都认为其它节点在它们之后停止的情况。在这种情况下,您可以在一个节点上使用 force_boot 命令使其可再次启动。
有关更多信息,请参阅 rabbitmqctl 手册页。
迁移 HA 和 Quorum 队列¶
在 2024.1 (Caracal) 版本中,OpenStack-Ansible 默认切换到使用 RabbitMQ Quorum 队列,而不是遗留的高可用性经典队列。可以升级时执行迁移到 Quorum 队列,但可能会导致扩展的控制平面停机时间,因为这需要使用新的配置重新启动所有 OpenStack 服务。
为了加快迁移速度,可以运行以下 playbook 以迁移到或从 Quorum 队列,同时跳过软件包安装和其他配置任务。这些任务从 2024.1 版本开始可用。
$ openstack-ansible openstack.osa.rabbitmq_server --tags rabbitmq-config $ openstack-ansible openstack.osa.setup_openstack --tags common-mq,post-install
为了利用这些步骤,我们建议在升级到 2024.1 之前将 oslomsg_rabbit_quorum_queues 设置为 false。然后,升级后,将 oslomsg_rabbit_quorum_queues 恢复为默认值 true 并运行上述 playbook。