Docker 部署 RabbitMQ 三节点集群

一、部署说明

本文介绍如何使用 Docker 在一台服务器上部署一个 RabbitMQ 三节点集群。

集群包含以下三个节点:

容器名称RabbitMQ 主机名AMQP 端口Web 管理端口
mq01rabbit01567115671
mq02rabbit02567215672
mq03rabbit03567315673

三个 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/rabbitmqRabbitMQ 数据目录
/var/log/rabbitmqRabbitMQ 日志目录
/etc/rabbitmqRabbitMQ 配置目录

六、启动第二个 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

注意,mq02mq03 都加入 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 集群。

整个部署过程主要包括:

  1. 创建 Docker 集群网络;
  2. 创建 RabbitMQ 数据、日志和配置目录;
  3. 启动三个 RabbitMQ 容器;
  4. 为三个节点配置相同的 Erlang Cookie;
  5. 将第二、第三个节点加入第一个节点所在的集群;
  6. 启用 RabbitMQ Web 管理插件;
  7. 创建远程管理用户;
  8. 检查集群节点运行状态。

需要特别注意,RabbitMQ 集群主要提供节点间的元数据共享。业务需要消息高可用时,还应结合仲裁队列等机制,避免队列所在节点故障后影响消息消费。

更多推荐