记录Docker 部署 RabbitMQ 三节点集群
Docker 部署 RabbitMQ 三节点集群
一、部署说明
本文介绍如何使用 Docker 在一台服务器上部署一个 RabbitMQ 三节点集群。
集群包含以下三个节点:
| 容器名称 | RabbitMQ 主机名 | AMQP 端口 | Web 管理端口 |
|---|---|---|---|
| mq01 | rabbit01 | 5671 | 15671 |
| mq02 | rabbit02 | 5672 | 15672 |
| mq03 | rabbit03 | 5673 | 15673 |
三个 RabbitMQ 容器通过自定义 Docker 网络进行通信,并使用相同的 Erlang Cookie 完成集群认证。
本文使用的 RabbitMQ 镜像为:
rabbitmq:3.8.7-management
management 版本的镜像已经包含 RabbitMQ Web 管理插件。
二、环境准备
部署前确认服务器已经安装 Docker:
docker version
查看 Docker 服务状态:
systemctl status docker
如果 Docker 服务没有启动,可以执行:
systemctl start docker
设置 Docker 开机自动启动:
systemctl enable docker
三、创建 Docker 网络
创建 RabbitMQ 集群专用网络:
docker network create rabbitmq-cluster
查看网络是否创建成功:
docker network ls
正常情况下可以看到:
rabbitmq-cluster
三个 RabbitMQ 容器加入同一个 Docker 网络后,可以直接通过容器主机名进行通信。
四、创建数据目录
创建三个 RabbitMQ 节点的数据、日志和配置目录:
mkdir -p /home/rabbitmq/{mq01,mq02,mq03}/{data,logs,config}
创建完成后的目录结构如下:
/home/rabbitmq
├── mq01
│ ├── config
│ ├── data
│ └── logs
├── mq02
│ ├── config
│ ├── data
│ └── logs
└── mq03
├── config
├── data
└── logs
为目录设置访问权限:
chmod -R 777 /home/rabbitmq
需要注意,777 权限配置比较宽松,适合测试环境快速部署。生产环境建议根据 RabbitMQ 容器运行用户设置更严格的目录权限。
五、启动第一个 RabbitMQ 节点
执行以下命令启动 mq01:
docker run -d \
--hostname rabbit01 \
--name mq01 \
--network rabbitmq-cluster \
-p 5671:5672 \
-p 15671:15672 \
-e RABBITMQ_ERLANG_COOKIE="javaboy_rabbitmq_cookie" \
-v /home/rabbitmq/mq01/data:/var/lib/rabbitmq \
-v /home/rabbitmq/mq01/logs:/var/log/rabbitmq \
-v /home/rabbitmq/mq01/config:/etc/rabbitmq \
rabbitmq:3.8.7-management
参数说明:
| 参数 | 说明 |
|---|---|
--hostname rabbit01 | 设置 RabbitMQ 节点主机名 |
--name mq01 | 设置 Docker 容器名称 |
--network rabbitmq-cluster | 加入 RabbitMQ 集群网络 |
-p 5671:5672 | 将宿主机 5671 映射到容器 AMQP 端口 5672 |
-p 15671:15672 | 将宿主机 15671 映射到 RabbitMQ 管理页面端口 |
RABBITMQ_ERLANG_COOKIE | 设置 RabbitMQ 集群认证 Cookie |
/var/lib/rabbitmq | RabbitMQ 数据目录 |
/var/log/rabbitmq | RabbitMQ 日志目录 |
/etc/rabbitmq | RabbitMQ 配置目录 |
六、启动第二个 RabbitMQ 节点
执行以下命令启动 mq02:
docker run -d \
--hostname rabbit02 \
--name mq02 \
--network rabbitmq-cluster \
-p 5672:5672 \
-p 15672:15672 \
-e RABBITMQ_ERLANG_COOKIE="javaboy_rabbitmq_cookie" \
-v /home/rabbitmq/mq02/data:/var/lib/rabbitmq \
-v /home/rabbitmq/mq02/logs:/var/log/rabbitmq \
-v /home/rabbitmq/mq02/config:/etc/rabbitmq \
rabbitmq:3.8.7-management
七、启动第三个 RabbitMQ 节点
执行以下命令启动 mq03:
docker run -d \
--hostname rabbit03 \
--name mq03 \
--network rabbitmq-cluster \
-p 5673:5672 \
-p 15673:15672 \
-e RABBITMQ_ERLANG_COOKIE="javaboy_rabbitmq_cookie" \
-v /home/rabbitmq/mq03/data:/var/lib/rabbitmq \
-v /home/rabbitmq/mq03/logs:/var/log/rabbitmq \
-v /home/rabbitmq/mq03/config:/etc/rabbitmq \
rabbitmq:3.8.7-management
八、检查容器运行状态
执行:
docker ps
正常情况下可以看到三个 RabbitMQ 容器:
mq01
mq02
mq03
也可以分别查看容器日志:
docker logs -f mq01
docker logs -f mq02
docker logs -f mq03
如果日志中没有明显错误,说明三个 RabbitMQ 节点已经正常启动。
九、启用 RabbitMQ 管理插件
由于本文使用的是:
rabbitmq:3.8.7-management
管理插件通常已经默认启用。
为了确保插件已经开启,可以分别执行:
docker exec mq01 rabbitmq-plugins enable rabbitmq_management
docker exec mq02 rabbitmq-plugins enable rabbitmq_management
docker exec mq03 rabbitmq-plugins enable rabbitmq_management
查看节点已启用的插件:
docker exec mq01 rabbitmq-plugins list
如果看到以下内容,说明管理插件已经启用:
[E*] rabbitmq_management
[E*] rabbitmq_management_agent
[E*] rabbitmq_web_dispatch
十、将第二个节点加入集群
RabbitMQ 节点名称通常由以下格式组成:
rabbit@主机名
因此,第一个节点的完整节点名称为:
rabbit@rabbit01
依次执行以下命令,将 mq02 加入 mq01 所在的集群。
1. 停止 RabbitMQ 应用
docker exec mq02 rabbitmqctl stop_app
2. 重置节点状态
docker exec mq02 rabbitmqctl reset
3. 加入第一个节点
docker exec mq02 rabbitmqctl join_cluster rabbit@rabbit01
4. 重新启动 RabbitMQ 应用
docker exec mq02 rabbitmqctl start_app
执行成功后,mq02 将成为 RabbitMQ 集群中的第二个节点。
十一、将第三个节点加入集群
依次执行以下命令,将 mq03 加入集群。
1. 停止 RabbitMQ 应用
docker exec mq03 rabbitmqctl stop_app
2. 重置节点状态
docker exec mq03 rabbitmqctl reset
3. 加入第一个节点
docker exec mq03 rabbitmqctl join_cluster rabbit@rabbit01
4. 重新启动 RabbitMQ 应用
docker exec mq03 rabbitmqctl start_app
注意,mq02 和 mq03 都加入 rabbit@rabbit01 所在的集群即可,不需要让 mq03 再加入 mq02。
十二、查看 RabbitMQ 集群状态
在任意节点执行以下命令:
docker exec mq01 rabbitmqctl cluster_status
也可以在第二个或第三个节点执行:
docker exec mq02 rabbitmqctl cluster_status
docker exec mq03 rabbitmqctl cluster_status
正常情况下,集群状态中应包含三个节点:
rabbit@rabbit01
rabbit@rabbit02
rabbit@rabbit03
示例输出:
Cluster status of node rabbit@rabbit01 ...
Basics
Cluster name: rabbit@rabbit01
Disk Nodes
rabbit@rabbit01
rabbit@rabbit02
rabbit@rabbit03
Running Nodes
rabbit@rabbit01
rabbit@rabbit02
rabbit@rabbit03
其中:
Disk Nodes表示集群中的磁盘节点;Running Nodes表示当前正在运行的节点;- 三个节点都出现在
Running Nodes中,说明集群运行正常。
十三、访问 RabbitMQ 管理页面
三个节点的管理页面地址分别为:
http://服务器IP:15671
http://服务器IP:15672
http://服务器IP:15673
例如服务器 IP 为 192.168.1.100,则访问地址为:
http://192.168.1.100:15671
http://192.168.1.100:15672
http://192.168.1.100:15673
默认用户名和密码通常为:
用户名:guest
密码:guest
但是 RabbitMQ 默认限制 guest 用户只能从本机登录。如果远程访问管理页面,建议创建一个新的管理员用户。
十四、创建 RabbitMQ 管理员用户
在第一个节点创建用户:
docker exec mq01 rabbitmqctl add_user admin admin123456
给用户设置管理员角色:
docker exec mq01 rabbitmqctl set_user_tags admin administrator
授予默认虚拟主机 / 的访问权限:
docker exec mq01 rabbitmqctl set_permissions -p / admin ".*" ".*" ".*"
由于用户、权限和虚拟主机信息会在 RabbitMQ 集群中同步,因此通常只需要在一个节点创建即可。
之后使用以下账号登录管理页面:
用户名:admin
密码:admin123456
生产环境应使用更复杂的密码,不建议直接使用示例密码。
查看当前用户列表:
docker exec mq01 rabbitmqctl list_users
十五、RabbitMQ 客户端连接地址
三个 RabbitMQ 节点的 AMQP 连接地址分别为:
服务器IP:5671
服务器IP:5672
服务器IP:5673
Spring Boot 可以配置多个 RabbitMQ 节点:
spring:
rabbitmq:
addresses: 192.168.1.100:5671,192.168.1.100:5672,192.168.1.100:5673
username: admin
password: admin123456
virtual-host: /
需要注意,客户端配置多个地址主要用于连接故障转移,并不等于队列中的消息已经自动复制到了所有节点。
十六、配置队列高可用
RabbitMQ 节点组成集群后,交换机、队列定义、用户和权限等元数据会在集群节点之间共享,但普通队列中的消息默认不会自动复制到其他节点。
对于需要高可用的业务队列,可以考虑使用仲裁队列。
创建队列时,将队列类型设置为:
quorum
Spring AMQP 示例:
@Bean
public Queue businessQueue() {
Map<String, Object> arguments = new HashMap<>();
arguments.put("x-queue-type", "quorum");
return new Queue(
"business.queue",
true,
false,
false,
arguments
);
}
仲裁队列会将消息复制到多个 RabbitMQ 节点,可以在部分节点故障时继续提供服务。
十七、常用运维命令
查看容器
docker ps
查看全部容器
docker ps -a
查看节点状态
docker exec mq01 rabbitmqctl status
查看集群状态
docker exec mq01 rabbitmqctl cluster_status
查看用户
docker exec mq01 rabbitmqctl list_users
查看虚拟主机
docker exec mq01 rabbitmqctl list_vhosts
查看队列
docker exec mq01 rabbitmqctl list_queues
查看交换机
docker exec mq01 rabbitmqctl list_exchanges
查看绑定关系
docker exec mq01 rabbitmqctl list_bindings
停止节点应用
docker exec mq01 rabbitmqctl stop_app
启动节点应用
docker exec mq01 rabbitmqctl start_app
重启容器
docker restart mq01
停止所有节点
docker stop mq01 mq02 mq03
启动所有节点
docker start mq01 mq02 mq03
十八、常见问题
1. 加入集群时提示节点无法连接
如果执行:
docker exec mq02 rabbitmqctl join_cluster rabbit@rabbit01
提示节点无法连接,需要检查 Docker 网络和主机名解析。
查看网络中的容器:
docker network inspect rabbitmq-cluster
测试 mq02 是否能解析 rabbit01:
docker exec mq02 ping rabbit01
如果容器中没有 ping 命令,可以检查 Erlang 节点诊断信息:
docker exec mq02 rabbitmq-diagnostics ping -n rabbit@rabbit01
2. Erlang Cookie 不一致
RabbitMQ 集群中的所有节点必须使用完全相同的 Erlang Cookie:
RABBITMQ_ERLANG_COOKIE="javaboy_rabbitmq_cookie"
如果 Cookie 不一致,节点之间无法建立集群连接。
可以分别查看三个容器中的 Cookie:
docker exec mq01 cat /var/lib/rabbitmq/.erlang.cookie
docker exec mq02 cat /var/lib/rabbitmq/.erlang.cookie
docker exec mq03 cat /var/lib/rabbitmq/.erlang.cookie
三次输出必须完全相同。
3. 节点名称不正确
RabbitMQ 节点名称与容器的 hostname 有关。
例如:
--hostname rabbit01
对应的 RabbitMQ 节点名称通常为:
rabbit@rabbit01
可以执行以下命令确认实际节点名称:
docker exec mq01 rabbitmqctl status
4. 远程无法使用 guest 登录
RabbitMQ 默认限制 guest 用户只能从本机访问。
远程访问时,应创建新的管理员用户:
docker exec mq01 rabbitmqctl add_user admin admin123456
docker exec mq01 rabbitmqctl set_user_tags admin administrator
docker exec mq01 rabbitmqctl set_permissions -p / admin ".*" ".*" ".*"
5. 管理页面无法打开
首先检查管理插件:
docker exec mq01 rabbitmq-plugins list
确认以下插件已经启用:
rabbitmq_management
rabbitmq_management_agent
rabbitmq_web_dispatch
然后检查端口映射:
docker port mq01
还需要检查服务器防火墙是否放行管理端口:
firewall-cmd --permanent --add-port=15671-15673/tcp
firewall-cmd --reload
同时放行 RabbitMQ AMQP 端口:
firewall-cmd --permanent --add-port=5671-5673/tcp
firewall-cmd --reload
6. 删除容器后重新部署失败
RabbitMQ 的节点和集群信息会保存在:
/home/rabbitmq/mq01/data
/home/rabbitmq/mq02/data
/home/rabbitmq/mq03/data
如果修改了 hostname、Cookie 或集群结构后重新部署,旧数据可能导致节点启动失败。
测试环境可以先删除容器:
docker rm -f mq01 mq02 mq03
然后清空旧数据:
rm -rf /home/rabbitmq/mq01/data/*
rm -rf /home/rabbitmq/mq02/data/*
rm -rf /home/rabbitmq/mq03/data/*
注意,清空数据目录会删除 RabbitMQ 中已有的队列、交换机、用户和消息,生产环境不能直接执行。
十九、停止并删除集群
停止三个 RabbitMQ 容器:
docker stop mq01 mq02 mq03
删除容器:
docker rm mq01 mq02 mq03
删除 Docker 网络:
docker network rm rabbitmq-cluster
如果确定不再保留 RabbitMQ 数据,可以删除数据目录:
rm -rf /home/rabbitmq
删除数据目录后,RabbitMQ 中的用户、队列、交换机和消息都无法恢复,执行前必须确认数据已经备份。
二十、完整部署命令汇总
1. 创建网络和目录
docker network create rabbitmq-cluster
mkdir -p /home/rabbitmq/{mq01,mq02,mq03}/{data,logs,config}
chmod -R 777 /home/rabbitmq
2. 启动三个节点
docker run -d \
--hostname rabbit01 \
--name mq01 \
--network rabbitmq-cluster \
-p 5671:5672 \
-p 15671:15672 \
-e RABBITMQ_ERLANG_COOKIE="javaboy_rabbitmq_cookie" \
-v /home/rabbitmq/mq01/data:/var/lib/rabbitmq \
-v /home/rabbitmq/mq01/logs:/var/log/rabbitmq \
-v /home/rabbitmq/mq01/config:/etc/rabbitmq \
rabbitmq:3.8.7-management
docker run -d \
--hostname rabbit02 \
--name mq02 \
--network rabbitmq-cluster \
-p 5672:5672 \
-p 15672:15672 \
-e RABBITMQ_ERLANG_COOKIE="javaboy_rabbitmq_cookie" \
-v /home/rabbitmq/mq02/data:/var/lib/rabbitmq \
-v /home/rabbitmq/mq02/logs:/var/log/rabbitmq \
-v /home/rabbitmq/mq02/config:/etc/rabbitmq \
rabbitmq:3.8.7-management
docker run -d \
--hostname rabbit03 \
--name mq03 \
--network rabbitmq-cluster \
-p 5673:5672 \
-p 15673:15672 \
-e RABBITMQ_ERLANG_COOKIE="javaboy_rabbitmq_cookie" \
-v /home/rabbitmq/mq03/data:/var/lib/rabbitmq \
-v /home/rabbitmq/mq03/logs:/var/log/rabbitmq \
-v /home/rabbitmq/mq03/config:/etc/rabbitmq \
rabbitmq:3.8.7-management
3. 启用管理插件
docker exec mq01 rabbitmq-plugins enable rabbitmq_management
docker exec mq02 rabbitmq-plugins enable rabbitmq_management
docker exec mq03 rabbitmq-plugins enable rabbitmq_management
4. 将 mq02 加入集群
docker exec mq02 rabbitmqctl stop_app
docker exec mq02 rabbitmqctl reset
docker exec mq02 rabbitmqctl join_cluster rabbit@rabbit01
docker exec mq02 rabbitmqctl start_app
5. 将 mq03 加入集群
docker exec mq03 rabbitmqctl stop_app
docker exec mq03 rabbitmqctl reset
docker exec mq03 rabbitmqctl join_cluster rabbit@rabbit01
docker exec mq03 rabbitmqctl start_app
6. 查看集群状态
docker exec mq01 rabbitmqctl cluster_status
7. 创建管理员用户
docker exec mq01 rabbitmqctl add_user admin admin123456
docker exec mq01 rabbitmqctl set_user_tags admin administrator
docker exec mq01 rabbitmqctl set_permissions -p / admin ".*" ".*" ".*"
二十一、总结
通过以上步骤,可以在一台服务器上使用 Docker 部署一个由三个节点组成的 RabbitMQ 集群。
整个部署过程主要包括:
- 创建 Docker 集群网络;
- 创建 RabbitMQ 数据、日志和配置目录;
- 启动三个 RabbitMQ 容器;
- 为三个节点配置相同的 Erlang Cookie;
- 将第二、第三个节点加入第一个节点所在的集群;
- 启用 RabbitMQ Web 管理插件;
- 创建远程管理用户;
- 检查集群节点运行状态。
需要特别注意,RabbitMQ 集群主要提供节点间的元数据共享。业务需要消息高可用时,还应结合仲裁队列等机制,避免队列所在节点故障后影响消息消费。
更多推荐
所有评论(0)