1. 准备工作
3台阿里云ECS服务器 (Rocky Linux 9.6 64位)
2.安装docker(3台服务器同样操作)
2.1 安装依赖
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
sudo yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
sudo yum install -y docker-ce docker-ce-cli containerd.io
2.2 配置docker镜像加速地址并启动
([ -f /etc/docker/daemon.json ] || mkdir -p /etc/docker) && echo '{ "registry-mirrors" : [
"https://docker.1ms.run","https://docker.1panel.live","https://docker.xuanyuan.me","https://registry-1.docker.io"]}' > /etc/docker/daemon.json && sudo systemctl restart docker && sleep 1 && docker info | grep -A 4 "Registry Mirrors"
3. docker部署rabbit
3.1 相关端口
- 4369:Erlang Port Mapper Daemon (epmd) 端口,用于节点发现和初始连接。当RabbitMQ节点启动时,它通过此端口注册自身并发现集群中的其他节点
- 5672:AMQP(Advanced Message Queueing Protocol)端口,用于客户端应用程序连接(如生产者/消费者发送和接收消息)
- 15672:RabbitMQ管理UI端口,提供Web-based的监控、配置和管理界面
- 25672:Erlang分布式通信端口,用于节点间数据传输(如消息复制、状态同步)。RabbitMQ使用此端口进行内部集群通信
3.2 使用bridge网络(单机集群)
# 创建文件夹
mkdir -p /usr/local/rabbitmq/{1,2,3}/{lib,log}
# 创建自定义bridge网络
docker network create my_bridge_net
# 创建容器1
docker run -d \
--hostname rabbit1 \
--name rabbitmq1 \
--network my_bridge_net \
-p 15672:15672 \
-p 5672:5672 \
-e RABBITMQ_NODENAME=rabbit@rabbit1 \
-e RABBITMQ_DEFAULT_USER=admin \
-e RABBITMQ_DEFAULT_PASS=123456 \
-e RABBITMQ_ERLANG_COOKIE='lanyu_rabbitmq_cookie' \
-v /usr/local/rabbitmq/1/lib:/var/lib/rabbitmq \
-v /usr/local/rabbitmq/1/log:/var/log/rabbitmq \
--privileged=true \
rabbitmq:3.8.9-management
# 创建容器2
docker run -d \
--hostname rabbit2 \
--name rabbitmq2 \
--network my_bridge_net \
-p 15673:15672 \
-p 5673:5672 \
-e RABBITMQ_NODENAME=rabbit@rabbit2 \
-e RABBITMQ_DEFAULT_USER=admin \
-e RABBITMQ_DEFAULT_PASS=123456 \
-e RABBITMQ_ERLANG_COOKIE='lanyu_rabbitmq_cookie' \
-v /usr/local/rabbitmq/2/lib:/var/lib/rabbitmq \
-v /usr/local/rabbitmq/2/log:/var/log/rabbitmq \
--privileged=true \
rabbitmq:3.8.9-management
# 创建容器3
docker run -d \
--hostname rabbit3 \
--name rabbitmq3 \
--network my_bridge_net \
-p 15674:15672 \
-p 5674:5672 \
-e RABBITMQ_NODENAME=rabbit@rabbit3 \
-e RABBITMQ_DEFAULT_USER=admin \
-e RABBITMQ_DEFAULT_PASS=123456 \
-e RABBITMQ_ERLANG_COOKIE='lanyu_rabbitmq_cookie' \
-v /usr/local/rabbitmq/3/lib:/var/lib/rabbitmq \
-v /usr/local/rabbitmq/3/log:/var/log/rabbitmq \
--privileged=true \
rabbitmq:3.8.9-management
默认bridge网络不支持解析功能 (即在下文中加入集群,解析不了rabbit@rabbit1)
3.2 使用host网络
#################### 节点1 ####################
mkdir -p /usr/local/rabbitmq/{lib,log}
docker run -d \
--hostname rabbit1 \
--name rabbitmq1 \
--network host \
--add-host rabbit1:172.19.146.151 \
--add-host rabbit2:172.19.240.110 \
--add-host rabbit3:172.19.240.111 \
-p 15672:15672 \
-p 5672:5672 \
-e RABBITMQ_NODENAME=rabbit@rabbit1 \
-e RABBITMQ_DEFAULT_USER=admin \
-e RABBITMQ_DEFAULT_PASS=123456 \
-e RABBITMQ_ERLANG_COOKIE='lanyu_rabbitmq_cookie' \
-v /usr/local/rabbitmq/lib:/var/lib/rabbitmq \
-v /usr/local/rabbitmq/log:/var/log/rabbitmq \
--privileged=true \
rabbitmq:3.8.9-management
#################### 节点2 ####################
mkdir -p /usr/local/rabbitmq/{lib,log}
docker run -d \
--hostname rabbit2 \
--name rabbitmq2 \
--network host \
--add-host rabbit1:172.19.146.151 \
--add-host rabbit2:172.19.240.110 \
--add-host rabbit3:172.19.240.111 \
-p 15672:15672 \
-p 5672:5672 \
-e RABBITMQ_NODENAME=rabbit@rabbit2 \
-e RABBITMQ_DEFAULT_USER=admin \
-e RABBITMQ_DEFAULT_PASS=123456 \
-e RABBITMQ_ERLANG_COOKIE='lanyu_rabbitmq_cookie' \
-v /usr/local/rabbitmq/lib:/var/lib/rabbitmq \
-v /usr/local/rabbitmq/log:/var/log/rabbitmq \
--privileged=true \
rabbitmq:3.8.9-management
#################### 节点3 ####################
mkdir -p /usr/local/rabbitmq/{lib,log}
docker run -d \
--hostname rabbit3 \
--name rabbitmq3 \
--network host \
--add-host rabbit1:172.19.146.151 \
--add-host rabbit2:172.19.240.110 \
--add-host rabbit3:172.19.240.111 \
-p 15672:15672 \
-p 5672:5672 \
-e RABBITMQ_NODENAME=rabbit@rabbit3 \
-e RABBITMQ_DEFAULT_USER=admin \
-e RABBITMQ_DEFAULT_PASS=123456 \
-e RABBITMQ_ERLANG_COOKIE='lanyu_rabbitmq_cookie' \
-v /usr/local/rabbitmq/lib:/var/lib/rabbitmq \
-v /usr/local/rabbitmq/log:/var/log/rabbitmq \
--privileged=true \
rabbitmq:3.8.9-management
3.4 使用overlay网络
#################### 节点1 ####################
# 初始化swarm集群
docker swarm init --advertise-addr <节点1IP>
# 创建overlay网络
docker network create -d overlay --attachable rabbit-net
# 创建文件夹
mkdir -p /usr/local/rabbitmq/{lib,log}
# 执行docker命令
docker run -d \
--hostname rabbit1 \
--name rabbitmq1 \
--network rabbit-net \
-p 15672:15672 \
-p 5672:5672 \
-e RABBITMQ_NODENAME=rabbit@rabbit1 \
-e RABBITMQ_DEFAULT_USER=admin \
-e RABBITMQ_DEFAULT_PASS=123456 \
-e RABBITMQ_ERLANG_COOKIE='lanyu_rabbitmq_cookie' \
-v /usr/local/rabbitmq/lib:/var/lib/rabbitmq \
-v /usr/local/rabbitmq/log:/var/log/rabbitmq \
--privileged=true \
rabbitmq:3.8.9-management
#################### 节点2 ####################
# 加入集群 (节点1执行 docker swarm init命令后,会输出该命令)
docker swarm join --token SWMTKN-1-xxxx xxxx:2377
# 创建文件夹
mkdir -p /usr/local/rabbitmq/{lib,log}
# 执行docker命令
docker run -d \
--hostname rabbit2 \
--name rabbitmq2 \
--network rabbit-net \
-p 15672:15672 \
-p 5672:5672 \
-e RABBITMQ_NODENAME=rabbit@rabbit2 \
-e RABBITMQ_DEFAULT_USER=admin \
-e RABBITMQ_DEFAULT_PASS=123456 \
-e RABBITMQ_ERLANG_COOKIE='lanyu_rabbitmq_cookie' \
-v /usr/local/rabbitmq/lib:/var/lib/rabbitmq \
-v /usr/local/rabbitmq/log:/var/log/rabbitmq \
--privileged=true rabbitmq:3.8.9-management
#################### 节点3 ####################
# 加入集群 (节点1执行 docker swarm init命令后,会输出该命令)
docker swarm join --token SWMTKN-1-xxxx xxxx:2377
# 创建文件夹
mkdir -p /usr/local/rabbitmq/{lib,log}
# 执行docker命令
docker run -d \
--hostname rabbit3 \
--name rabbitmq3 \
--network rabbit-net \
-p 15672:15672 \
-p 5672:5672 \
-e RABBITMQ_NODENAME=rabbit@rabbit3 \
-e RABBITMQ_DEFAULT_USER=admin \
-e RABBITMQ_DEFAULT_PASS=123456 \
-e RABBITMQ_ERLANG_COOKIE='lanyu_rabbitmq_cookie' \
-v /usr/local/rabbitmq/lib:/var/lib/rabbitmq \
-v /usr/local/rabbitmq/log:/var/log/rabbitmq \
--privileged=true rabbitmq:3.8.9-management
docker swarm init 输出如下

4. 加入集群
# 节点1配置集群
docker exec -it rabbitmq1 bash
rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl start_app
exit
# 节点2加入集群,--ram是以内存方式加入,忽略该参数默认为磁盘节点。
docker exec -it rabbitmq2 bash
rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl join_cluster --ram rabbit@rabbit1
rabbitmqctl start_app
exit
# 节点3加入集群,--ram是以内存方式加入,忽略该参数默认为磁盘节点。
docker exec -it rabbitmq3 bash
rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl join_cluster rabbit@rabbit1
rabbitmqctl start_app
exit
# 查看集群节点状态,配置启动了3个节点,2个磁盘节点和1个内存节点
rabbitmqctl cluster_status
-
内存节点(ram):将元数据都放在内存里,内存节点的话,只要服务重启,该节点的所有数据将会丢失
-
硬盘节点(disc):将元数据都放在硬盘里,所以服务重启的话,数据也还是会存在的
-
在RabbitMQ集群里,至少有一个磁盘节点,它用来持久保存元数据;考虑到高可用性,推荐在集群里保持2个磁盘节点
加入集群时设置节点为内存节点
rabbitmqctl join_cluster --ram rabbit@rabbit1
通过命令修改节点的类型
rabbitmqctl change_cluster_node_type disc | ram
5. 将普通集群设置为镜像集群
# 查看所有策略
docker exec -it rabbitmq1 rabbitmqctl list_policies -p "/"
# 将普通镜像设置为集群镜像
docker exec -it rabbitmq1 rabbitmqctl set_policy -p "/" ha-all "^" '{"ha-mode":"all", "ha-sync-mode":"automatic"}'
5.1 集群重启顺序
- 启动顺序:磁盘节点 => 内存节点
- 关闭顺序:内存节点 => 磁盘节点
- 最后关闭必须是磁盘节点,否则容易造成集群启动失败、数据丢失等异常情况
6. MQ高可用集群架构-Haproxy方案
Haproxy在RabbitMQ中充当负载均衡器的角色,提供负载均衡、故障转移、可靠性和可用性增强以及动态伸缩
6.1 配置文件组成
- 全局(Global)配置部分
- 定义了全局级别的配置指令,会影响整个HAProxy实例的行为
- 例如,可以设置代理服务器的进程数、日志文件和日志级别,以及系统的最大连接数等。
- 默认(Default)配置部分
- 这部分定义了默认的配置指令,会应用于没有明确指定配置的特定配置块或监听器
- 在这里设置的参数可以被后续的配置块覆盖或继承。
- 前端(Frontend)部分
- 定义接收客户端请求的前端配置块没,设置监听的IP地址和端口,以及请求的代理方式、负载均衡算法和ACL等规则。
- 后端(Backend)部分
- 定义了后端服务器池及其相关配置,可以指定服务器的IP地址和端口
- 设置健康检查方式、故障转移规则和会话保持等选项。
- 配置块(Block)
- HAProxy的配置文件还可以包含其他自定义配置块,用于更精细地定义不同的逻辑组件和行为
- 例如,像使用ACL(访问控制列表)配置请求过滤和路由规则等
- 对比nginx
- fronted:相当于nginx, server {}
- backend:相当于nginx, upstream {}
6.2 配置haproxy.cfg
# 创建文件夹
mkdir -p /usr/local/haproxy
# 编辑haproxy.cfg
vim haproxy.cfg
# 增加下面配置文件
global
# 设置日志输出目标为本地地址127.0.0.1的local0日志设备,并设置日志级别为info
log 127.0.0.1 local0 info
# 设置最大连接数为10240`。
maxconn 10240
# 启用后台运行模式
daemon
defaults
# 设置日志输出为全局设定的日志设备。
log global
# 指定工作模式为HTTP模式
mode http
# 设置连接超时时间为3000毫秒。
timeout connect 3000
# 设置客户端超时时间为3000毫秒。
timeout client 3000
# 设置服务器超时时间为3000毫秒。
timeout server 3000
# 设置健康检查超时时间为2000毫秒。
timeout check 2000
listen admin_stats
# 监听0.0.0.0:8081地址和端口。
bind 0.0.0.0:8081
# 使用HTTP模式。
mode http
# 设置监控统计信息的路径为/stats。
stats uri /stats
# 设置统计信息页面的显示名称为Global statistics。
stats realm Global\ statistics
# 设置访问统计信息页面的认证用户名和密码为admin:123456。
stats auth admin:123456
listen rabbitmq_admin
# rabbit的监控页面
bind 0.0.0.0:8082
# 配置了三个RabbitMQ管理节点
server rabbit_admin1 172.19.146.151:15672
server rabbit_admin2 172.19.240.110:15672
server rabbit_admin3 172.19.240.111:15672
listen haproxy
# 监听0.0.0.0:5666地址和端口。
bind 0.0.0.0:5666
# 启用TCP日志记录。
option tcplog
# 使用TCP模式。
mode tcp
# 使用轮询算法进行负载均衡
balance roundrobin
# 设置了健康检查的参数:每5000毫秒检查一次,如果连续2次检查成功就认为节点上线,如果连续2次检查失败则认为节点宕机。
server rabbitmq1 172.19.146.151:5672 check inter 5000 rise 2 fall 2
server rabbitmq2 172.19.240.110:5672 check inter 5000 rise 2 fall 2
server rabbitmq3 172.19.240.111:5672 check inter 5000 rise 2 fall 2
6.3 部署haproxy
docker run -d \
--name haproxy-rabbitmq \
--network rabbit-net \
-p 8081:8081 \
-p 8082:8082 \
-p 5666:5666 \
-v /usr/local/haproxy/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg \
haproxy:latest
6.3.1 访问地址
- Haproxy: http://公网IP:8081/stats
- RabbitMQ管控台: http://公网IP:8082
6.3.2 Haproxy界面示例

6.4 SpringBoot连接Haproxy配置
spring:
rabbitmq:
host: 您的IP地址
port: 5666 # haproxy.cfg中配置的listen haproxy
username: admin
password: 123456
virtual-host: /