|
|
|
|
公众号矩阵

快速搭建高可用RabbitMQ集群和HAProxy软负载

将两个 RabbitMQ 磁盘节点和一个 RabbitMQ 内存节点组成一个内建集群,之所以要用两个磁盘节点是防止,唯一的磁盘节点挂掉后,不能重建队列,交换器

作者:佚名来源:马哥Linux运维|2020-10-28 11:20

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 内建集群,持久化队列无法在队列节点崩溃时,自动连接别的节点创建队列,非持久化队列可以自动连接可用节点创建队列。我们的项目使用的非持久化队列。

至少保证有两个磁盘节点,否则在唯一磁盘节点崩溃时,无法在集群中创建队列,交换器等元数据。

服务分布情况

  1. 192.168.1.213 服务器部署 RabbitMQ Disc Node1。  
  2. 192.168.1.203 服务器部署 RabbitMQ Disc Node2。  
  3. 192.168.1.212 服务器部署 RabbitMQ RAM Node3。 

创建第一个 RabbitMQ 节点

登录服务器,创建目录 /app/mcst/rabbitmq。

将镜像 tar 包 rabbitmq.tar,服务编排文件 mcst-rabbitmq-node1.yaml 通过 sftp 上传到刚创建的目录下。

导入镜像

  1. $ docker load -i rabbitmq.tar  
  2. $ docker images # 查看是否导入成功 

查看服务编排文件 mcst-rabbitmq-node1.yaml

  1. version: '3'  
  2. services:  
  3.   rabbitmq:  
  4.     container_name: mcst-rabbitmq  
  5.     image: rabbitmq:3-management  
  6.     restart: always  
  7.     ports:  
  8.       - 4369:4369  
  9.       - 5671:5671  
  10.       - 5672:5672  
  11.       - 15672:15672  
  12.       - 25672:25672  
  13.     environment:  
  14.       - TZ=Asia/Shanghai  
  15.       - RABBITMQ_ERLANG_COOKIE=iweru238roseire  
  16.       - RABBITMQ_DEFAULT_USER=mcst_admin  
  17.       - RABBITMQ_DEFAULT_PASS=mcst_admin_123  
  18.       - RABBITMQ_DEFAULT_VHOST=mcst_vhost  
  19.     hostname: rabbitmq1  
  20.     extra_hosts:  
  21.       - rabbitmq1:192.168.1.213  
  22.       - rabbitmq2:192.168.1.203  
  23.       - rabbitmq3:192.168.1.212  
  24.     volumes:  
  25.       - ./data:/var/lib/rabbitmq 

部署命令

  1. $ docker-compose -f mcst-rabbitmq-node1.yaml up -d 

注意:三个节点 RABBITMQ_ERLANG_COOKIE 保持一致。一定要有 extra_hosts 配置,否则在搭建集群的过程中会连接不到其他 rabbitmq 节点服务。此节点作为集群根节点。

部署第二个 RabbitMQ 节点

方法同上,上传 rabbitmq.sh 脚本到 volumes 配置的 ./rabbitmq.sh 路径。查看 mcst-rabbitmq-node2.yaml

  1. version: '3'  
  2. services:  
  3.   rabbitmq:  
  4.     container_name: mcst-rabbitmq  
  5.     image: rabbitmq:3-management  
  6.     restart: always  
  7.     ports:  
  8.       - 4369:4369  
  9.       - 5671:5671  
  10.       - 5672:5672  
  11.       - 15672:15672  
  12.       - 25672:25672  
  13.     environment:  
  14.       - TZ=Asia/Shanghai  
  15.       - RABBITMQ_ERLANG_COOKIE=iweru238roseire  
  16.       - RABBITMQ_DEFAULT_USER=mcst_admin  
  17.       - RABBITMQ_DEFAULT_PASS=mcst_admin_123  
  18.       - RABBITMQ_DEFAULT_VHOST=mcst_vhost  
  19.     hostname: rabbitmq2  
  20.     extra_hosts:  
  21.       - rabbitmq1:192.168.1.213  
  22.       - rabbitmq2:192.168.1.203  
  23.       - rabbitmq3:192.168.1.212  
  24.     volumes:  
  25.       - ./rabbitmq.sh:/home/rabbitmq.sh  
  26.       - ./data:/var/lib/rabbitmq 

部署命令

  1. $ docker-compose -f mcst-rabbitmq-node2.yaml up -d 

节点启动完成后,通过命令进入 rabbitmq2 节点的容器中,执行 /home/rabbitmq.sh 脚本。如果报权限错误,则在容器内执行 chmod +x /home/rabbitmq.sh 赋权,然后 bash /home/rabbitmq.sh 执行脚本添加到集群中。

进入容器的命令:

  1. $ docker exec -it mcst-rabbitmq /bin/bash 

脚本内容如下(磁盘节点):

  1. rabbitmqctl stop_app  
  2. rabbitmqctl reset  
  3. rabbitmqctl join_cluster rabbit@rabbitmq1 
  4. rabbitmqctl start_app 

部署第三个 RabbitMQ 节点

方法同上,查看 mcst-rabbitmq-node3.yaml

  1. version: '3'  
  2. services:  
  3.   rabbitmq:  
  4.     container_name: mcst-rabbitmq  
  5.     image: rabbitmq:3-management  
  6.     restart: always  
  7.     ports:  
  8.       - 4369:4369  
  9.       - 5671:5671  
  10.       - 5672:5672  
  11.       - 15672:15672  
  12.       - 25672:25672  
  13.     environment:  
  14.       - TZ=Asia/Shanghai  
  15.       - RABBITMQ_ERLANG_COOKIE=iweru238roseire  
  16.       - RABBITMQ_DEFAULT_USER=mcst_admin  
  17.       - RABBITMQ_DEFAULT_PASS=mcst_admin_123  
  18.       - RABBITMQ_DEFAULT_VHOST=mcst_vhost  
  19.     hostname: rabbitmq3  
  20.     extra_hosts:  
  21.       - rabbitmq1:192.168.1.213  
  22.       - rabbitmq2:192.168.1.203  
  23.       - rabbitmq3:192.168.1.212  
  24.     volumes:  
  25.       - ./rabbitmq-ram.sh:/home/rabbitmq-ram.sh  
  26.       - ./data:/var/lib/rabbitmq 

部署命令

  1. $ docker-compose -f mcst-rabbitmq-node3.yaml up -d 

在启动 rabbitmq3 节点,启动后,进入容器内部,执行 bash /home/rabbitmq-ram.sh 脚本添加内存节点到集群中。

脚本内容:

  1. rabbitmqctl stop_app  
  2. rabbitmqctl reset  
  3. rabbitmqctl join_cluster --ram rabbit@rabbitmq1  
  4. rabbitmqctl start_app 

在容器内部使用命令查看集群状态:rabbitmqctl cluster_status。

  1. Cluster status of node rabbit@rabbitmq1 ...  
  2. [{nodes,[{disc,[rabbit@rabbitmq1,rabbit@rabbitmq2]},{ram,[rabbit@rabbitmq3]}]},  
  3.  {running_nodes,[rabbit@rabbitmq2,rabbit@rabbitmq3,rabbit@rabbitmq1]},  
  4.  {cluster_name,<<"rabbit@rabbitmq2">>},  
  5.  {partitions,[]},  
  6.  {alarms,[{rabbit@rabbitmq2,[]},{rabbit@rabbitmq3,[]},{rabbit@rabbitmq1,[]}]}] 

也可以通过 http://192.168.1.213:15672 进入管理端查看集群状态。

HAProxy 负载均衡

创建目录 /app/mcst/haproxy,将镜像 tar 包,haproxy 配置文件,docker 服务编排文件上传到该目录。

导入镜像方法同上。

查看服务编排文件内容:

  1. version: '3'  
  2. services:  
  3.   haproxy:  
  4.     container_name: mcst-haproxy  
  5.     image: haproxy:2.1  
  6.     restart: always  
  7.     ports:  
  8.       - 8100:8100  
  9.       - 15670:5670  
  10.     environment:  
  11.       - TZ=Asia/Shanghai  
  12.     extra_hosts:  
  13.       - rabbitmq1:192.168.1.213  
  14.       - rabbitmq2:192.168.1.203  
  15.       - rabbitmq3:192.168.1.212  
  16.     volumes:  
  17.       - ./haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro 

重点是设置 extra_hosts(rabbitmq 集群节点 ip) 和 volumes(使用自定义的配置文件)。

haproxy 配置文件内容:

  1. global  
  2.     log 127.0.0.1 local0 info  
  3.     maxconn 4096  
  4. defaults  
  5.     log     global  
  6.     mode    tcp  
  7.     option  tcplog  
  8.     retries 3  
  9.     option  redispatch  
  10.     maxconn 2000  
  11.     timeout connect 5s  
  12.     timeout client 120s  
  13.     timeout server 120s  
  14. # ssl for rabbitmq  
  15. # frontend ssl_rabbitmq  
  16.     # bind *:5673 ssl crt /root/rmqha_proxy/rmqha.pem  
  17.     # mode tcp  
  18.     # default_backend rabbitmq  
  19. # web 管理界面  
  20. listen stats  
  21.     bind *:8100  
  22.     mode http  
  23.     stats enable  
  24.     stats realm Haproxy\ Statistics  
  25.     stats uri /  
  26.     stats auth admin:admin123  
  27. # 配置负载均衡  
  28. listen rabbitmq 
  29.      bind *:5670  
  30.     mode tcp  
  31.     balance roundrobin  
  32.     server  rabbitmq1 rabbitmq1:5672  check inter 5s rise 2 fall 3  
  33.     server  rabbitmq2 rabbitmq2:5672  check inter 5s rise 2 fall 3  
  34.     server  rabbitmq3 rabbitmq3:5672  check inter 5s rise 2 fall 3 

部署命令

  1. $ docker-compose -f mcst-haproxy.yaml up -d 

服务分布情况

  1. 192.168.1.212 服务器部署 HAProxy Master。  
  2. 192.168.1.203 服务器部署 HAProxy Backup。 

分别在以上两个节点起好 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 包解压缩。

  1. $ tar -xf keepalived-2.0.20.tar.gz 

检查依赖

  1. $ cd keepalived-2.0.20  
  2. $ ./configure 

Keepalived 的安装需要以下依赖 gcc,openssl-devel。

安装命令

  1. $ yum install -y gcc  
  2. $ yum install -y openssl-devel 

因为是内网服务器不能使用外网的 yum 源,所以需要更改用本地 yum 源。

将 linux 的安装光盘镜像上传到 /mnt/iso 目录下,并 mount 到 /mnt/cdrom 目录下,作为 yum 的一个安装源。

  1. $ mkdir /mnt/iso  
  2. $ mkdir /mnt/cdrom   
  3. $ mv /ftp/rhel-server-7.3-x86_64-dvd.iso /mnt/iso 

挂载光盘镜像

  1. $ mount -ro loop /mnt/iso/rhel-server-7.3-x86_64-dvd.iso /mnt/cdrom   
  2. $ mv /ftp/myself.repo /etc/yum.repos.d  
  3. $ yum clean all   
  4. $ yum makecache   
  5. $ yum update 

附:myself.repo文件内容:

  1. [base]  
  2. nameRed Hat  Enterprise Linux $releasever  -  $basearch  -  Source  
  3. baseurl=file:///mnt/cdrom  
  4. enabled=1  
  5. gpgcheck=1  
  6. gpgkey=file:///mnt/cdrom/RPM-GPG-KEY-redhat-release 

更改完成后,以后每次需要 linux 安装盘安装软件包时,只需要执行 mount 命令,将光盘 ISO 文件加载即可。

  1. $ mount -ro loop /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.”

安装如下依赖解决

  1. $ yum install -y libnl libnl-devel 

安装完成后再次 ./configure 就没问题了。

然后执行 make 编译

最后执行 make install 安装

安装完成后执行 keepalived --version,输出版本号即为安装成功。

创建 Keepalived 配置文件

创建配置文件 /etc/keepalived/keepalived.conf

Master 节点配置:

  1. vrrp_script chk_haproxy {  
  2.     script "killall -0 haproxy"  # verify haproxy's pid existance  
  3.     interval 5                   # check every 2 seconds  
  4.     weight -2                    # if check failed, priority will minus 2  
  5.  
  6. vrrp_instance VI_1 {  
  7.     # 主机: MASTER  
  8.     # 备机: BACKUP  
  9.     state MASTER  
  10.     # 实例绑定的网卡, 用ip a命令查看网卡编号  
  11.     interface ens192  
  12.     # 虚拟路由标识,这个标识是一个数字(1-255),在一个VRRP实例中主备服务器ID必须一样  
  13.     virtual_router_id 51  
  14.     # 优先级,数字越大优先级越高,在一个实例中主服务器优先级要高于备服务器  
  15.     priority 101  
  16.     # 虚拟IP地址,可以有多个,每行一个  
  17.     virtual_ipaddress {  
  18.         192.168.1.110  
  19.     }  
  20.     track_script {               # Scripts state we monitor  
  21.         chk_haproxy                
  22.     }  

ens192 是网卡名,ifconfig 命令查看服务器网卡,找到和本机服务 ip 对应的网卡,virtual_router_id 的值要和 backup 节点上的配置保持一致。killall \-0 haproxy 命令的意思是,如果 haproxy 服务存在执行该命令,什么都不会发生,如果服务不存在,执行该命令会报找不到进程 haproxy: no process found。

  1. # 网卡信息  
  2. ens192: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500  
  3.         inet 192.168.1.203  netmask 255.255.255.0  broadcast 192.168.1.255  
  4.         inet6 fe80::250:56ff:fe94:bceb  prefixlen 64  scopeid 0x20<link>  
  5.         ether 00:50:56:94:bc:eb  txqueuelen 1000  (Ethernet)  
  6.         RX packets 88711011  bytes 12324982140 (11.4 GiB)  
  7.         RX errors 0  dropped 272  overruns 0  frame 0  
  8.         TX packets 88438149  bytes 10760989492 (10.0 GiB)  
  9.         TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0  
  10. # haproxy 服务不存在  
  11. [root@localhost ~]# killall -0 haproxy  
  12. haproxy: no process found 

master 节点的 priority 在减去 weight 后要比 backup 节点的 priority 低才行,否则主备切换不成功。

Backup节点配置:

  1. vrrp_script chk_haproxy {  
  2.     script "killall -0 haproxy"  # verify haproxy's pid existance  
  3.     interval 5                   # check every 2 seconds  
  4.     weight -2                    # if check failed, priority will minus 2 
  5.  
  6. vrrp_instance VI_1 {  
  7.     # 主机: MASTER  
  8.     # 备机: BACKUP  
  9.     state BACKUP  
  10.     # 实例绑定的网卡, 用ip a命令查看网卡编号  
  11.     interface ens192  
  12.     # 虚拟路由标识,这个标识是一个数字(1-255),在一个VRRP实例中主备服务器ID必须一样  
  13.     virtual_router_id 51  
  14.     # 优先级,数字越大优先级越高,在一个实例中主服务器优先级要高于备服务器  
  15.     priority 100  
  16.     # 虚拟IP地址,可以有多个,每行一个  
  17.     virtual_ipaddress { 
  18.          192.168.1.110  
  19.     }  
  20.     track_script {               # Scripts state we monitor  
  21.         chk_haproxy                
  22.     } 
  23.  

创建完配置,启动 keepalived。

  1. $ systemctl restart keepalived 

测试 Keepalived

在 Master,Backup 节点上,使用 ip addr 命令看下 vip 在哪台机器的 ens192 网卡上。

  1. 2: ens192: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000  
  2.     link/ether 00:50:56:94:c1:79 brd ff:ff:ff:ff:ff:ff  
  3.     inet 192.168.1.212/24 brd 192.168.1.255 scope global ens192  
  4.        valid_lft forever preferred_lft forever  
  5.     inet 192.168.1.110/32 scope global ens192  
  6.        valid_lft forever preferred_lft forever  
  7.     inet6 fe80::250:56ff:fe94:c179/64 scope link   
  8.        valid_lft forever preferred_lft forever 

默认在 master 主机上,停掉 master 主机的 haproxy 服务,然后在用 ip addr 查看虚拟 ip 在哪个机器上,如果漂移到备份主机上则代表热备生效。

在开启 master 主机的 haproxy 服务,ip addr 查看虚拟ip应该重新漂移回 master 主机上。

测试服务,使用虚拟 ip 加服务端口号访问 HAProxy 服务。

至此,高可用的 rabbitmq 集群 和 haproxy 软负载就搭建完成。

【编辑推荐】

  1. 运维必看!这里有 CAP 分布式最易懂的解释
  2. RabbitMQ如何保证消息的可靠投递?
  3. 如何从零思考设计你的 DevOps 运维服务体系?
  4. 详解负载神器 LVS、Nginx及HAProxy工作原理
  5. 运维必备:Zookeeper集群“脑裂”问题处理大全
【责任编辑:庞桂玉 TEL:(010)68476606】

点赞 0
分享:
大家都在看
猜你喜欢

订阅专栏+更多

云原生架构实践

云原生架构实践

新技术引领移动互联网进入急速赛道
共3章 | KaliArch

26人订阅学习

数据中心和VPDN网络建设案例

数据中心和VPDN网络建设案例

漫画+案例
共20章 | 捷哥CCIE

189人订阅学习

搭建数据中心实验Lab

搭建数据中心实验Lab

实验平台Datacenter
共5章 | ITGO(老曾)

118人订阅学习

订阅51CTO邮刊

点击这里查看样刊

订阅51CTO邮刊

51CTO服务号

51CTO官微