系统环境:Centos7.6
Docker version: 1.13.1, build 7d71120/1.13.1
Docker Compose version: v2.2.2
三个节点:
10.10.11.79 (这一台做rabbitmq集群根节点)
10.10.11.80 (这台做haproxy+keepalived高可用 master节点)
10.10.11.81 (这台做haproxy+keepalived高可用 backup节点)
RabbitMQ 集群中节点包括内存节点(RAM)、 磁盘节点(Disk, 消息持久化), 集群中至少有一个 Disk 节点。
10.10.11.79,10.10.11.80做磁盘节点,10.10.11.81做内存节点。
下面开始先搭建普通集群模式,此方案只适用非持久化非持久化队列。
三个节点都创建文件夹/home/rabbitmq,注意挂载目录的权限问题。
version: '3'
services:
rabbitmq:
container_name: mcst-rabbitmq
image: rabbitmq:3-management
restart: always
ports:
- 4369:4369
- 5671:5671
- 5672:5672
- 15672:15672
- 25672:25672
environment:
- TZ=Asia/Shanghai
- RABBITMQ_ERLANG_COOKIE=iweru238roseire
- RABBITMQ_DEFAULT_USER=mcst_admin
- RABBITMQ_DEFAULT_PASS=mcst_admin_123
- RABBITMQ_DEFAULT_VHOST=mcst_vhost
hostname: rabbitmq1
extra_hosts:
- rabbitmq1:10.10.11.79
- rabbitmq2:10.10.11.80
- rabbitmq3:10.10.11.81
volumes:
- ./data:/var/lib/rabbitmq
注意:三个节点 RABBITMQ_ERLANG_COOKIE 保持一致。一定要有 extra_hosts 配置,否则在搭建集群的过程中会连接不到其他 rabbitmq 节点服务。此节点作为集群根节点。
docker-compose -f mcst-rabbitmq-node1.yaml up -d
docker-compose -f mcst-rabbitmq-node1.yaml stop
version: '3'
services:
rabbitmq:
container_name: mcst-rabbitmq
image: rabbitmq:3-management
restart: always
ports:
- 4369:4369
- 5671:5671
- 5672:5672
- 15672:15672
- 25672:25672
environment:
- TZ=Asia/Shanghai
- RABBITMQ_ERLANG_COOKIE=iweru238roseire
- RABBITMQ_DEFAULT_USER=mcst_admin
- RABBITMQ_DEFAULT_PASS=mcst_admin_123
- RABBITMQ_DEFAULT_VHOST=mcst_vhost
hostname: rabbitmq2
extra_hosts:
- rabbitmq1:10.10.11.79
- rabbitmq2:10.10.11.80
- rabbitmq3:10.10.11.81
volumes:
- ./node2-rabbitmq.sh:/home/node2-rabbitmq.sh
- ./data:/var/lib/rabbitmq
另外在同目录下面需要编辑一个脚本node2-rabbitmq.sh:
rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl join_cluster rabbit@rabbitmq1
rabbitmqctl start_app
docker-compose -f mcst-rabbitmq-node2.yaml up -d
docker-compose -f mcst-rabbitmq-node2.yaml stop
docker exec -it mcst-rabbitmq bash
执行脚本将当前节点添加到集群中(注意文件执行权限):
cd home
sh node2-rabbitmq.sh
执行脚本的时候可能会报这个错误:
Error: unable to perform an operation on node 'rabbit@rabbitmq2'
没有ping通
把节点2的防火墙关闭:
systemctl stop firewalld
重启docker:
systemctl restart docker
重启容器:
docker start mcst-rabbitmq
version: '3'
services:
rabbitmq:
container_name: mcst-rabbitmq
image: rabbitmq:3-management
restart: always
ports:
- 4369:4369
- 5671:5671
- 5672:5672
- 15672:15672
- 25672:25672
environment:
- TZ=Asia/Shanghai
- RABBITMQ_ERLANG_COOKIE=iweru238roseire
- RABBITMQ_DEFAULT_USER=mcst_admin
- RABBITMQ_DEFAULT_PASS=mcst_admin_123
- RABBITMQ_DEFAULT_VHOST=mcst_vhost
hostname: rabbitmq3
extra_hosts:
- rabbitmq1:10.10.11.79
- rabbitmq2:10.10.11.80
- rabbitmq3:10.10.11.81
volumes:
- ./rabbitmq-ram.sh:/home/rabbitmq-ram.sh
- ./data:/var/lib/rabbitmq
同目录下建一个脚本rabbitmq-ram.sh:
rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl join_cluster --ram rabbit@rabbitmq1
rabbitmqctl start_app
docker-compose -f mcst-rabbitmq-node3.yaml up -d
docker exec -it mcst-rabbitmq bash
执行脚本, 把内存节点到集群中:
sh rabbitmq-ram.sh
如果第三个几点启动的时候报链接不上根节点:
把根节点(10.10.11.79)的网络端口打开:
查看端口是否开放
firewall-cmd --query-port=4369/tcp
开放端口
firewall-cmd --permanent --add-port=4369/tcp
重启防火墙
firewall-cmd --reload
查看:
http://10.10.11.79:15672 进入管理端查看集群状态。
这三节点的个ip 都可以访问,
用户:mcst_admin 密码:mcst_admin_123
将rabbitmq2,rabbitmq3的节点加入rabbitmq1中创建普通集群,集群就已经搭建好了。
这里使用addresses 链接多个ip。
spring:
rabbitmq:
# rabbitmq集群地址
addresses: 10.10.11.79:5672,10.10.11.80:5672,10.10.11.81:5672
username: test
password: 123456
#虚拟host
virtual-host: mcst_vhost
在普通模式的基础上,还把需要的队列做成镜像队列,存在于多个节点来实现高可用(HA):haproxy+keepalived高可用集群
用 HAProxy 作为 RabbitMQ 集群的负载均衡。
因为79是集群的根节点,所以我们在80,81两个节点上建立文件夹/home/haproxy
需要创建两个文件,
version: '3'
services:
haproxy:
container_name: mcst-haproxy
image: haproxy:2.1
restart: always
ports:
- 8100:8100
- 15670:5670
environment:
- TZ=Asia/Shanghai
extra_hosts:
- rabbitmq1:10.10.11.79
- rabbitmq2:10.10.11.80
- rabbitmq3:10.10.11.81
volumes:
- ./haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro
设置 extra_hosts(rabbitmq 集群节点 ip) 和 volumes(使用自定义的配置文件
)
global
log 127.0.0.1 local0 info
maxconn 4096
defaults
log global
mode tcp
option tcplog
retries 3
option redispatch
maxconn 2000
timeout connect 5s
timeout client 120s
timeout server 120s
# ssl for rabbitmq
# frontend ssl_rabbitmq
# bind *:5673 ssl crt /root/rmqha_proxy/rmqha.pem
# mode tcp
# default_backend rabbitmq
# web 管理界面
listen stats
bind *:8100
mode http
stats enable
stats realm Haproxy\ Statistics
stats uri /
stats auth admin:admin123
# 配置负载均衡
listen rabbitmq
bind *:5670
mode tcp
balance roundrobin
server rabbitmq1 rabbitmq1:5672 check inter 5s rise 2 fall 3
server rabbitmq2 rabbitmq2:5672 check inter 5s rise 2 fall 3
server rabbitmq3 rabbitmq3:5672 check inter 5s rise 2 fall 3
两个节点使用相同的配置。
docker-compose -f mcst-haproxy.yaml up -d
HAProxy Master:10.10.11.80
HAProxy Backup:10.10.11.81
用户:admin
密码:admin123
http://10.10.11.80:8100/
为了防止 HAProxy 单点故障,用 Keepalived 将两个 HAProxy 节点做成一主一备。应用使用 VIP(虚拟IP) 访问 HAProxy 服务时,默认连接主机(Master)的 HAProxy,当主机(Master)上的 HAProxy 故障时,VIP 会漂移到备机(Backup)上,就会连接备机(Backup)上的 HAProxy 服务。
如果其中一个节点的HAProxy 服务挂了,我们也要保证服务是可用的,这样就需要健康检测服务Keepalived,使用keepalived搭建双主热备。
yum clean all
yum install -y keepalived
systemctl start keepalived.service #启动keepalived
systemctl stop keepalived.service #停止keepalived
systemctl status keepalived.service #查看keepalived状态
创建配置文件 /etc/keepalived/keepalived.conf:
vrrp_script chk_haproxy {
script "killall -0 haproxy" # verify haproxy's pid existance
interval 5 # check every 2 seconds
weight -2 # if check failed, priority will minus 2
}
vrrp_instance VI_1 {
# 主机: MASTER
# 备机: BACKUP
state MASTER
# 实例绑定的网卡, 用ip a命令查看网卡编号
interface ens192
# 虚拟路由标识,这个标识是一个数字(1-255),在一个VRRP实例中主备服务器ID必须一样
virtual_router_id 51
# 优先级,数字越大优先级越高,在一个实例中主服务器优先级要高于备服务器
priority 101
# 虚拟IP地址,可以有多个,每行一个
virtual_ipaddress {
10.10.11.77
}
track_script { # Scripts state we monitor
chk_haproxy
}
}
创建配置文件 /etc/keepalived/keepalived.conf:
vrrp_script chk_haproxy {
script "killall -0 haproxy" # verify haproxy's pid existance
interval 5 # check every 2 seconds
weight -2 # if check failed, priority will minus 2
}
vrrp_instance VI_1 {
# 主机: MASTER
# 备机: BACKUP
state BACKUP
# 实例绑定的网卡, 用ip a命令查看网卡编号
interface ens192
# 虚拟路由标识,这个标识是一个数字(1-255),在一个VRRP实例中主备服务器ID必须一样
virtual_router_id 51
# 优先级,数字越大优先级越高,在一个实例中主服务器优先级要高于备服务器
priority 100
# 虚拟IP地址,可以有多个,每行一个
virtual_ipaddress {
10.10.11.77
}
track_script { # Scripts state we monitor
chk_haproxy
}
}
systemctl restart keepalived
http://10.10.11.77:15672
用户:mcst_admin 密码:mcst_admin_123
使用keepalived的虚拟ip链接
spring:
rabbitmq:
#rabbitmq集群虚拟ip地址
host: 10.10.11.77
port: 5672
username: test
password: 123456
#虚拟host
virtual-host: mcst_vhost
1.mq的端口号,是5672,不是访问浏览器时候的15672
2.不要使用默认账户,新建用户添加相关的权限
3.Springboot链接配置种是否配置了virtual-host
4.ip+5672 查看一下服务器网络端口是不是开放了