RabbitMQ 高可用集群架构
将两个 RabbitMQ 磁盘节点和一个 RabbitMQ 内存节点组成一个内建集群,之所以要用两个磁盘节点是防止,唯一的磁盘节点挂掉后,不能重建队列,交换器。用 HAProxy 作为 RabbitMQ 集群的负载均衡。为了防止 HAProxy 单点故障,用 Keepalived 将两个 HAProxy 节点做成一主一备。应用使用 VIP(虚拟IP) 访问 HAProxy 服务时,默认连接主机(Master)的 HAProxy,当主机(Master)上的 HAProxy 故障时,VIP 会漂移到备机(Backup)上,就会连接备机(Backup)上的 HAProxy 服务。
准备工作
服务器安装 docker,docker-compose,准备离线镜像 rabbitmq.tar,haproxy.tar。
服务器节点间可以相互 ping 通。
RabbitMQ 集群
使用 RabbitMQ 内建集群,持久化队列无法在队列节点崩溃时,自动连接别的节点创建队列,非持久化队列可以自动连接可用节点创建队列。我们的项目使用的非持久化队列。
至少保证有两个磁盘节点,否则在唯一磁盘节点崩溃时,无法在集群中创建队列,交换器等元数据。
服务分布情况
192.168.1.213服务器部署RabbitMQDiscNode1。 192.168.1.203服务器部署RabbitMQDiscNode2。 192.168.1.212服务器部署RabbitMQRAMNode3。
创建第一个 RabbitMQ 节点
登录服务器,创建目录 /app/mcst/rabbitmq。
将镜像 tar 包 rabbitmq.tar,服务编排文件 mcst-rabbitmq-node1.yaml 通过 sftp 上传到刚创建的目录下。
导入镜像
$dockerload-irabbitmq.tar $dockerimages#查看是否导入成功
查看服务编排文件 mcst-rabbitmq-node1.yaml
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:192.168.1.213 -rabbitmq2:192.168.1.203 -rabbitmq3:192.168.1.212 volumes: -./data:/var/lib/rabbitmq
部署命令
$docker-compose-fmcst-rabbitmq-node1.yamlup-d
注意:三个节点 RABBITMQ_ERLANG_COOKIE 保持一致。一定要有 extra_hosts 配置,否则在搭建集群的过程中会连接不到其他 rabbitmq 节点服务。此节点作为集群根节点。
部署第二个 RabbitMQ 节点
方法同上,上传 rabbitmq.sh 脚本到 volumes 配置的 ./rabbitmq.sh 路径。查看 mcst-rabbitmq-node2.yaml
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:192.168.1.213 -rabbitmq2:192.168.1.203 -rabbitmq3:192.168.1.212 volumes: -./rabbitmq.sh:/home/rabbitmq.sh -./data:/var/lib/rabbitmq
部署命令
$docker-compose-fmcst-rabbitmq-node2.yamlup-d
节点启动完成后,通过命令进入 rabbitmq2 节点的容器中,执行 /home/rabbitmq.sh 脚本。如果报权限错误,则在容器内执行 chmod +x /home/rabbitmq.sh 赋权,然后 bash /home/rabbitmq.sh 执行脚本添加到集群中。
进入容器的命令:
$dockerexec-itmcst-rabbitmq/bin/bash
脚本内容如下(磁盘节点):
rabbitmqctlstop_app rabbitmqctlreset rabbitmqctljoin_clusterrabbit@rabbitmq1 rabbitmqctlstart_app
部署第三个 RabbitMQ 节点
方法同上,查看 mcst-rabbitmq-node3.yaml
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:192.168.1.213 -rabbitmq2:192.168.1.203 -rabbitmq3:192.168.1.212 volumes: -./rabbitmq-ram.sh:/home/rabbitmq-ram.sh -./data:/var/lib/rabbitmq
部署命令
$docker-compose-fmcst-rabbitmq-node3.yamlup-d
在启动 rabbitmq3 节点,启动后,进入容器内部,执行 bash /home/rabbitmq-ram.sh 脚本添加内存节点到集群中。
脚本内容:
rabbitmqctlstop_app rabbitmqctlreset rabbitmqctljoin_cluster--ramrabbit@rabbitmq1 rabbitmqctlstart_app
在容器内部使用命令查看集群状态:rabbitmqctl cluster_status。
Clusterstatusofnoderabbit@rabbitmq1... [{nodes,[{disc,[rabbit@rabbitmq1,rabbit@rabbitmq2]},{ram,[rabbit@rabbitmq3]}]}, {running_nodes,[rabbit@rabbitmq2,rabbit@rabbitmq3,rabbit@rabbitmq1]}, {cluster_name,<<"rabbit@rabbitmq2">>}, {partitions,[]}, {alarms,[{rabbit@rabbitmq2,[]},{rabbit@rabbitmq3,[]},{rabbit@rabbitmq1,[]}]}]
也可以通过 http://192.168.1.213:15672 进入管理端查看集群状态。
HAProxy 负载均衡
创建目录 /app/mcst/haproxy,将镜像 tar 包,haproxy 配置文件,docker 服务编排文件上传到该目录。
导入镜像方法同上。
查看服务编排文件内容:
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:192.168.1.213 -rabbitmq2:192.168.1.203 -rabbitmq3:192.168.1.212 volumes: -./haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro
重点是设置 extra_hosts(rabbitmq 集群节点 ip) 和 volumes(使用自定义的配置文件)。
haproxy 配置文件内容:
global log127.0.0.1local0info maxconn4096 defaults logglobal modetcp optiontcplog retries3 optionredispatch maxconn2000 timeoutconnect5s timeoutclient120s timeoutserver120s #sslforrabbitmq #frontendssl_rabbitmq #bind*:5673sslcrt/root/rmqha_proxy/rmqha.pem #modetcp #default_backendrabbitmq #web管理界面 listenstats bind*:8100 modehttp statsenable statsrealmHaproxy\Statistics statsuri/ statsauthadmin:admin123 #配置负载均衡 listenrabbitmq bind*:5670 modetcp balanceroundrobin serverrabbitmq1rabbitmq1:5672checkinter5srise2fall3 serverrabbitmq2rabbitmq2:5672checkinter5srise2fall3 serverrabbitmq3rabbitmq3:5672checkinter5srise2fall3
部署命令
$docker-compose-fmcst-haproxy.yamlup-d
服务分布情况
192.168.1.212服务器部署HAProxyMaster。 192.168.1.203服务器部署HAProxyBackup。
分别在以上两个节点起好 HAProxy 服务。
登录 HAProxy 的管理端查看集群状态:http://192.168.1.212:8100/。
使用 Keepalived 给 HAProxy 做主备
准备工作
申请一个和服务节点同一局域网的 ip 地址,该 ip 不能被占用,作为 VIP(虚拟ip)。
安装 Keepalived
到 Keepalived 官网下载最新版本包,本次安装使用的是 2.0.20 版本。
下载好后的文件是:keepalived-2.0.20.tar.gz。
上传到服务器,对 tar 包解压缩。
$tar-xfkeepalived-2.0.20.tar.gz
检查依赖
$cdkeepalived-2.0.20 $./configure
Keepalived 的安装需要以下依赖 gcc,openssl-devel。
安装命令
$yuminstall-ygcc $yuminstall-yopenssl-devel
因为是内网服务器不能使用外网的 yum 源,所以需要更改用本地 yum 源。
将 linux 的安装光盘镜像上传到 /mnt/iso 目录下,并 mount 到 /mnt/cdrom 目录下,作为 yum 的一个安装源。
$mkdir/mnt/iso $mkdir/mnt/cdrom $mv/ftp/rhel-server-7.3-x86_64-dvd.iso/mnt/iso
挂载光盘镜像
$mount-roloop/mnt/iso/rhel-server-7.3-x86_64-dvd.iso/mnt/cdrom $mv/ftp/myself.repo/etc/yum.repos.d $yumcleanall $yummakecache $yumupdate
附:myself.repo文件内容:
[base] name=RedHatEnterpriseLinux$releasever-$basearch-Source baseurl=file:///mnt/cdrom enabled=1 gpgcheck=1 gpgkey=file:///mnt/cdrom/RPM-GPG-KEY-redhat-release
更改完成后,以后每次需要 linux 安装盘安装软件包时,只需要执行 mount 命令,将光盘 ISO 文件加载即可。
$mount-roloop/mnt/iso/rhel-server-7.3-x86_64-dvd.iso/mnt/cdrom
这时使用 yum 安装 gcc,openssl-devel就没问题了。
如果使用本地 yum 源的条件也不具备,那么可以使用 yum 的 downloadonly 插件。
要在能连接外网和系统版本一致的机器上将需要的依赖下载下来,到目标内网机器上本地安装。
还是推荐使用本地 yum 源的方式
安装完 gcc,openssl-devel 后,再次执行 ./configure 会报一个警告。
“this build will not support IPVS with IPv6. Please install libnl/libnl-3 dev libraries to support IPv6 with IPVS.”
安装如下依赖解决
$yuminstall-ylibnllibnl-devel
安装完成后再次 ./configure 就没问题了。
然后执行 make 编译
最后执行 make install 安装
安装完成后执行 keepalived –version,输出版本号即为安装成功。
创建 Keepalived 配置文件
创建配置文件 /etc/keepalived/keepalived.conf
Master 节点配置:
vrrp_scriptchk_haproxy{ script"killall-0haproxy"#verifyhaproxy'spidexistance interval5#checkevery2seconds weight-2#ifcheckfailed,prioritywillminus2 } vrrp_instanceVI_1{ #主机:MASTER #备机:BACKUP stateMASTER #实例绑定的网卡,用ipa命令查看网卡编号 interfaceens192 #虚拟路由标识,这个标识是一个数字(1-255),在一个VRRP实例中主备服务器ID必须一样 virtual_router_id51 #优先级,数字越大优先级越高,在一个实例中主服务器优先级要高于备服务器 priority101 #虚拟IP地址,可以有多个,每行一个 virtual_ipaddress{ 192.168.1.110 } track_script{#Scriptsstatewemonitor chk_haproxy } }
ens192 是网卡名,ifconfig 命令查看服务器网卡,找到和本机服务 ip 对应的网卡,virtual_router_id 的值要和 backup 节点上的配置保持一致。killall \-0 haproxy 命令的意思是,如果 haproxy 服务存在执行该命令,什么都不会发生,如果服务不存在,执行该命令会报找不到进程 haproxy: no process found。
#网卡信息 ens192:flags=4163<UP,BROADCAST,RUNNING,MULTICAST>mtu1500 inet192.168.1.203netmask255.255.255.0broadcast192.168.1.255 inet6fe80::250:56ff:fe94:bcebprefixlen64scopeid0x20<link> ether00:50:56:94:bc:ebtxqueuelen1000(Ethernet) RXpackets88711011bytes12324982140(11.4GiB) RXerrors0dropped272overruns0frame0 TXpackets88438149bytes10760989492(10.0GiB) TXerrors0dropped0overruns0carrier0collisions0 #haproxy服务不存在 [root@localhost~]#killall-0haproxy haproxy:noprocessfound
master 节点的 priority 在减去 weight 后要比 backup 节点的 priority 低才行,否则主备切换不成功。
Backup节点配置:
vrrp_scriptchk_haproxy{ script"killall-0haproxy"#verifyhaproxy'spidexistance interval5#checkevery2seconds weight-2#ifcheckfailed,prioritywillminus2 } vrrp_instanceVI_1{ #主机:MASTER #备机:BACKUP stateBACKUP #实例绑定的网卡,用ipa命令查看网卡编号 interfaceens192 #虚拟路由标识,这个标识是一个数字(1-255),在一个VRRP实例中主备服务器ID必须一样 virtual_router_id51 #优先级,数字越大优先级越高,在一个实例中主服务器优先级要高于备服务器 priority100 #虚拟IP地址,可以有多个,每行一个 virtual_ipaddress{ 192.168.1.110 } track_script{#Scriptsstatewemonitor chk_haproxy } }
创建完配置,启动 keepalived。
$systemctlrestartkeepalived
测试 Keepalived
在 Master,Backup 节点上,使用 ip addr 命令看下 vip 在哪台机器的 ens192 网卡上。
2:ens192:<BROADCAST,MULTICAST,UP,LOWER_UP>mtu1500qdiscmqstateUPqlen1000 link/ether00:50:56:94:c1:79brdff:ff:ff:ff:ff:ff inet192.168.1.212/24brd192.168.1.255scopeglobalens192 valid_lftforeverpreferred_lftforever inet192.168.1.110/32scopeglobalens192 valid_lftforeverpreferred_lftforever inet6fe80::250:56ff:fe94:c179/64scopelink valid_lftforeverpreferred_lftforever
默认在 master 主机上,停掉 master 主机的 haproxy 服务,然后在用 ip addr 查看虚拟 ip 在哪个机器上,如果漂移到备份主机上则代表热备生效。
在开启 master 主机的 haproxy 服务,ip addr 查看虚拟ip应该重新漂移回 master 主机上。
测试服务,使用虚拟 ip 加服务端口号访问 HAProxy 服务。
至此,高可用的 rabbitmq 集群 和 haproxy 软负载就搭建完成。