一、环境准备
构建环境
操作系统:ubuntu24.04.1 LTS
Docker版本:27.5.1
修改主机名
主机名不能相同
hostnamectl set-hostname node1 192.168.59.128
hostnamectl set-hostname node2 192.168.59.129
hostnamectl set-hostname node3 192.168.59.130
设置主机名解析(每台服务器执行)
cat <<EOF | sudo tee -a /etc/hosts
192.168.59.128 node1
192.168.59.129 node2
192.168.59.130 node3
EOF
# 验证解析:
ping node2 # 在所有节点应能解析
开放必要端口
sudo ufw allow 4369/tcp # Erlang 端口映射
sudo ufw allow 5672/tcp # AMQP
sudo ufw allow 15672/tcp # 管理界面
sudo ufw allow 25672/tcp # Erlang 分布式节点
sudo ufw reload
创建共享配置文件(所有服务器)
# 创建配置目录
mkdir -p ~/rabbitmq/config
# 创建 rabbitmq.conf 配置文件
cat <<EOF > ~/rabbitmq/config/rabbitmq.conf
cluster_formation.peer_discovery_backend = rabbit_peer_discovery_classic_config
cluster_formation.classic_config.nodes.1 = rabbit@node1
cluster_formation.classic_config.nodes.2 = rabbit@node2
cluster_formation.classic_config.nodes.3 = rabbit@node3
loopback_users = none
management.tcp.port = 15672
management.tcp.ip = 0.0.0.0 # 确保绑定所有接口
EOF
# 创建相同的 Erlang cookie(必须完全一致!)
echo "MY_SECRET_COOKIE" > ~/rabbitmq/.erlang.cookie
chmod 600 ~/rabbitmq/.erlang.cookie
拉取镜像
docker pull rabbitmq:3.13-management
二、搭建RabbitMQ集群
在 rabbitmq1 (192.168.59.128):
docker run -d \
--name rabbitmq1 \
--network host \
--add-host=node1:192.168.59.128 \
--add-host=node2:192.168.59.129 \
--add-host=node3:192.168.59.130 \
-p 5672:5672 \
-p 15672:15672 \
-v ~/rabbitmq/config:/etc/rabbitmq \
-v ~/rabbitmq/.erlang.cookie:/var/lib/rabbitmq/.erlang.cookie \
-e RABBITMQ_NODENAME=rabbit@node1 \
-e RABBITMQ_DEFAULT_USER=admin \
-e RABBITMQ_DEFAULT_PASS=adminpassword \
rabbitmq:3.13-management
在 rabbitmq2 (192.168.59.129):
docker run -d \
--name rabbitmq2 \
--network host \
--add-host=node1:192.168.59.128 \
--add-host=node2:192.168.59.129 \
--add-host=node3:192.168.59.130 \
-p 5672:5672 \
-p 15673:15672 \
-v ~/rabbitmq/config:/etc/rabbitmq \
-v ~/rabbitmq/.erlang.cookie:/var/lib/rabbitmq/.erlang.cookie \
-e RABBITMQ_NODENAME=rabbit@node2 \
-e RABBITMQ_DEFAULT_USER=admin \
-e RABBITMQ_DEFAULT_PASS=adminpassword \
rabbitmq:3.13-management
在 rabbitmq3 (192.168.59.130):
docker run -d \
--name rabbitmq3 \
--network host \
--add-host=node1:192.168.59.128 \
--add-host=node2:192.168.59.129 \
--add-host=node3:192.168.59.130 \
-p 5672:5672 \
-p 15674:15672 \
-v ~/rabbitmq/config:/etc/rabbitmq \
-v ~/rabbitmq/.erlang.cookie:/var/lib/rabbitmq/.erlang.cookie \
-e RABBITMQ_NODENAME=rabbit@node3 \
-e RABBITMQ_DEFAULT_USER=admin \
-e RABBITMQ_DEFAULT_PASS=adminpassword \
rabbitmq:3.13-management
三、验证集群状态
在node1节点执行
docker exec rabbitmq1 rabbitmqctl cluster_status
应看到类似输出:
# Cluster status of node rabbit@rabbitmq1
# [{nodes,[{disc,[rabbit@rabbitmq1,rabbit@rabbitmq2,rabbit@rabbitmq3]}]},
# {running_nodes,[rabbit@rabbitmq3,rabbit@rabbitmq2,rabbit@rabbitmq1]}]
四、配置高可用(镜像集群)
在任意节点执行策略配置
docker exec rabbitmq1 rabbitmqctl set_policy ha-all "^" \
'{"ha-mode":"all","ha-sync-mode":"automatic"}'
验证策略
docker exec rabbitmq1 rabbitmqctl list_policies
输出应包含:
root@node1:~# docker exec rabbitmq1 rabbitmqctl list_policies
Listing policies for vhost "/" ...
vhost name pattern apply-to definition priority
/ ha-all ^ all {"ha-mode":"exactly","ha-params":2,"ha-sync-mode":"automatic"} 0
五、访问管理界面
启用插件
docker exec rabbitmq1 rabbitmq-plugins enable rabbitmq_management
docker exec rabbitmq2 rabbitmq-plugins enable rabbitmq_management
docker exec rabbitmq3 rabbitmq-plugins enable rabbitmq_management
访问任意节点的管理界面:
http://192.168.59.128:15672/#/
http://192.168.59.129:15672/#/
http://192.168.59.130:15672/#/
使用账号:admin 密码:adminpassword
六、验证消息同步
- 创建测试队列
-
- 点击顶部菜单“Queues”
- 点击“Add a new Queue”
- 输入参数Name:“mirror_test_queue”、Durability: Durable (持久化)、Arguments: 留空
- 点击 "Add queue"
- 发送测试消息
-
- 在队列列表中找到 mirror_test_queue,点击进入详情页
- 滚动到 "Publish message" 区域
- 输入消息内容:
{
"text": "Hello from node1!",
"timestamp": "2025-07-23T10:00:00Z"
}
-
- 点击 "Publish Message"
- 验证消息同步
-
- 方法一:查看所有节点的队列状态,
节点 访问地址 检查位置 预期结果
node1 http://192.168.59.128:15672 Queues → mirror_test_queue Ready: 1 条消息
node2 http://192.168.59.129:15673 Queues → mirror_test_queue Ready: 1 条消息
node3 http://192.168.59.130:15674 Queues → mirror_test_queue Ready: 1 条消息
-
- 方法二:在任意节点的队列详情页:
-
-
- 找到 "Mirrors" 区域
- 检查所有节点状态:1 个节点标记为 master(主节点)、其他节点标记为 mirror(镜像节点)
-
- 模拟主节点故障
-
- 停止主节点容器(假设主节点是 node1):docker stop rabbitmq1
- 等待 10 秒,RabbitMQ 会自动选举新主节点
- 访问存活节点的管理界面(如 http://192.168.59.129:15673)
- 检查:
-
-
- 队列 mirror_test_queue 依然存在
- 消息数量仍为 1
- 新主节点显示在 "Mirrors" 顶部
-
-
- 消费消息验证
-
-
- 在任意存活节点执行,在队列详情页滚动到 "Get messages" 区域
- 点击 "Get Message(s)"
- 查看返回的消息内容应与发送的一致
-
七、故障排查
- 节点无法加入集群
-
- 检查所有节点的 .erlang.cookie 文件内容完全一致
- 验证主机名解析:docker exec rabbitmq1 ping rabbitmq2
- 检查防火墙开放端口:4369, 25672 bash
# 检查cookie一致性
docker exec rabbitmq1 cat /var/lib/rabbitmq/.erlang.cookie
docker exec rabbitmq2 cat /var/lib/rabbitmq/.erlang.cookie
docker exec rabbitmq3 cat /var/lib/rabbitmq/.erlang.cookie
# 测试容器间网络
docker exec rabbitmq1 ping node2
docker exec rabbitmq1 ping node3
# 检查端口连通性(在node1上测试node2)
telnet node2 4369
telnet node2 25672
- Web 界面无法访问
# 检查容器状态
docker ps -a | grep rabbitmq
# 查看容器日志
docker logs rabbitmq1
# 检查服务状态
docker exec rabbitmq1 rabbitmqctl status
- 节点状态不一致
# 重置节点(在问题节点执行)
docker exec rabbitmq2 rabbitmqctl stop_app
docker exec rabbitmq2 rabbitmqctl reset
docker exec rabbitmq2 rabbitmqctl join_cluster rabbit@node1
docker exec rabbitmq2 rabbitmqctl start_app
- 应用未启动
# 手动启动应用(所有节点)
docker exec rabbitmq1 rabbitmqctl start_app
docker exec rabbitmq2 rabbitmqctl start_app
docker exec rabbitmq3 rabbitmqctl start_app
- 容器启动后自动退出
# 查看容器日志
docker logs rabbitmq1
# 常见原因:
# 1. cookie权限问题:确保宿主机cookie文件权限为600
# 2. 端口冲突:检查4369、25672端口是否被占用
# 3. 主机名解析失败:确保容器内能解析node1/node2/node3