部署RabbitMQ主备集群的分步指南
构建RabbitMQ主备架构,涵盖集群配置、Erlang Cookie匹配、仲裁队列及经过验证的故障转移路径。
部署RabbitMQ主备集群的分步指南
RabbitMQ的高可用性不仅仅需要两台能够互相通信的服务器。你需要集群来实现共享元数据、复制队列来保证消息可用性,以及为客户端提供清晰的故障转移路径。
本指南展示了RabbitMQ在主备风格部署中的配置。客户端的故障转移通常由负载均衡器、DNS变更、服务发现或RabbitMQ外部的虚拟IP管理。
主备集群的先决条件
在开始配置之前,请确保所有目标集群节点(节点A-主节点,节点B-备节点)满足以下先决条件:
- 兼容的软件版本: 保持各节点上的RabbitMQ Server和Erlang/OTP版本一致。实践中,除非遵循RabbitMQ官方文档的滚动升级路径,否则应在每个节点上运行相同的RabbitMQ版本。
- 网络可达性: 节点必须能够通过客户端使用的AMQP端口、用于集群的分布端口以及你启用的任何管理或TLS端口进行通信。
- 主机名解析: 在所有节点上配置
/etc/hosts文件(或DNS),使每个节点能够可靠地解析其他所有节点的主机名。 - Cookie一致性: 所有节点上的Erlang“魔法cookie”必须完全相同。这对于节点之间相互信任以进行集群至关重要。
确保Cookie一致性
Erlang cookie决定了节点之间能否安全通信。必须将其从第一个初始化的节点复制到所有其他节点。
在节点A(第一个节点)上:
找到cookie文件(通常位于/var/lib/rabbitmq/.erlang.cookie或~/.erlang.cookie,具体取决于安装方式)并复制其内容。
在节点B(及后续节点)上:
- 停止RabbitMQ服务:
sudo systemctl stop rabbitmq-server - 用从节点A复制的内容替换现有的cookie文件,并确保正确的权限(通常为
400)。# 使用echo的示例(根据需要替换内容) echo "YOUR_LONG_COOKIE_STRING" | sudo tee /var/lib/rabbitmq/.erlang.cookie sudo chmod 400 /var/lib/rabbitmq/.erlang.cookie - 在节点B上启动服务:
sudo systemctl start rabbitmq-server
步骤1:配置主机名和网络
确保节点A和节点B上的主机文件正确映射了它们的主机名。
示例/etc/hosts(在两台服务器上):
192.168.1.10 rabbitmq-node-a
192.168.1.11 rabbitmq-node-b
步骤2:初始化第一个集群节点(主节点)
节点A将是初始主节点,集群首先在此建立。
- 在节点A上启动服务(如果尚未运行):
sudo systemctl start rabbitmq-server - 验证状态: 确保节点正常运行。
rabbitmqctl status
步骤3:将第二个节点(备节点)加入集群
现在,我们指示节点B加入由节点A领导的集群。
停止节点B上的RabbitMQ应用程序,同时保持Erlang节点可用:
sudo rabbitmqctl stop_app重置节点B的本地状态(如果它已被初始化为独立节点):
sudo rabbitmqctl reset加入命令: 在节点B上执行加入命令,指定节点A的主机名作为对等节点。
sudo rabbitmqctl join_cluster rabbit@rabbitmq-node-a提示:使用在
/etc/hosts中定义的主机名。在节点B上启动RabbitMQ应用程序:
sudo rabbitmqctl start_app
步骤4:验证集群形成
登录到节点A并验证两个节点是否相互识别。
rabbitmqctl cluster_status
预期输出片段:
你应该看到rabbitmq-node-a和rabbitmq-node-b都列在running_nodes下。
Cluster status of node rabbit@rabbitmq-node-a ...
[{nodes,[{disc,[rabbit@rabbitmq-node-a,rabbit@rabbitmq-node-b]}]},
{running_nodes,[rabbit@rabbitmq-node-a,rabbit@rabbitmq-node-b]},
...
]
步骤5:配置队列的高可用性
标准的RabbitMQ集群共享元数据,例如用户、交换机、绑定和策略。如果你希望消息在节点故障时仍然存在,队列内容需要复制队列类型。
对于现代RabbitMQ部署,使用仲裁队列来实现复制的持久队列。在较旧的RabbitMQ版本中,经典镜像队列使用ha-mode策略,但该方法已被弃用,并从新的主要版本中移除。
声明一个仲裁队列
你可以从应用程序或使用rabbitmqadmin声明仲裁队列。此示例创建一个持久化的仲裁队列:
rabbitmqadmin declare queue name=orders durable=true arguments='{"x-queue-type":"quorum"}'
对于双节点实验室环境,仲裁队列可以运行,但它无法容忍丢失一个节点并仍然保持多数。对于生产环境,请至少使用三个RabbitMQ节点来运行仲裁队列,这样即使一个节点故障,队列仍然拥有多数节点。
步骤6:测试故障转移
在宣布集群就绪之前,测试客户端将使用的路径:
- 向仲裁队列发布几条持久化的测试消息。
- 使用
sudo rabbitmqctl stop_app停止主节点的RabbitMQ应用程序。 - 确认客户端通过你的负载均衡器、DNS目标或服务发现设置重新连接。
- 从幸存节点消费测试消息。
- 使用
sudo rabbitmqctl start_app再次启动已停止的应用程序,并检查rabbitmqctl cluster_status。
最终总结
RabbitMQ集群为你提供共享的代理元数据,但队列的可用性取决于队列类型和客户端故障转移设计。使用仲裁队列实现复制的持久队列,至少保留三个节点以实现真正的容错,并使用应用程序使用的相同连接路径测试故障转移。