RabbitMQ-高可用集群
搭建RabbitMQ集群
参考上一篇【RabbitMQ-普通集群】
搭建 HAProxy 负载均衡
HAProxy 是一个免费的负载均衡软件,可以运行于大部分主流的 Linux 操作系统上。
Haproxy 是目前比较流行的一种群集调度工具,是使用C语言编写的自由及开放源代码软件,其提供高可用性、负载均衡,以及基于TCP和HTTP的应用程序代理。同类群集调度工具有很多,如LVS 和 Nginx 。相比较而言,LVS 性能最好,但是搭建相对复杂,Nginx的upstream模块支持群集功能,但是对群集节点的健康检查功能不强,性能没有HAProxy 好。
HAProxy 提供了 L4(TCP) 和 L7(HTTP) 两种负载均衡能力,具备丰富的功能。HAProxy 的社区非常活跃,版本更新快速(最新稳定版 1.7.2 于 2017/01/13 推出)。最关键的是,HAProxy 具备媲美商用负载均衡器的性能和稳定性。它当前不仅仅是免费负载均衡软件的首选,更几乎成为了唯一选择。
因为 RabbitMQ 本身不提供负载均衡,下面我们就搭建 HAProxy,用作 RabbitMQ 集群的负载均衡。
部署HAProxy
haproxy容器部署
容器名称 |
管理端口 |
haproxy_01 |
4001 |
haproxy_02 |
4002 |
拉取docker镜像
创建HAProxy配置文件
创建一个HAProxy的配置文件haproxy.cfg
1
| vi /tmp/etc/haproxy/haproxy.cfg
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
| global
chroot /usr/local/etc/haproxy
log 127.0.0.1 local5 info
daemon defaults log global
mode http
retries 2
option redispatch
option abortonclose
option httplog
option dontlognull
maxconn 4096
timeout connect 5000
timeout client 50000
timeout server 50000
listen admin_stats
bind 0.0.0.0:8888
mode http
stats uri /dbs
stats realm Global\ statistics
stats auth admin:admin
listen proxy-rabbitMQ-web
bind 0.0.0.0:5000
mode tcp
balance roundrobin
option tcplog
server rabbitmq_01 172.18.0.2:15672 check weight 1 maxconn 2000 server rabbitmq_02 172.18.0.3:15672 check weight 1 maxconn 2000 server rabbitmq_03 172.18.0.4:15672 check weight 1 maxconn 2000
option tcpka
listen proxy-rabbitMQ
bind 0.0.0.0:5010
mode tcp
balance roundrobin
option tcplog
server rabbitmq_01 172.18.0.2:5672 check weight 1 maxconn 2000 server rabbitmq_02 172.18.0.3:5672 check weight 1 maxconn 2000 server rabbitmq_03 172.18.0.4:5672 check weight 1 maxconn 2000
option tcpka
|
将配置文件放在宿主机目录交给容器挂载
启动docker容器
1 2 3
| docker run -d --network=rabbitmq_net --ip=172.18.0.5 -v /tmp/etc/haproxy:/usr/local/etc/haproxy -p 4001:8888 -p 5000:5000 -p 5010:5010 --name=haproxy_01 --privileged=true haproxy
docker run -d --network=rabbitmq_net --ip=172.18.0.6 -v /tmp/etc/haproxy:/usr/local/etc/haproxy -p 4002:8888 -p 5001:5000 -p 5011:5010 --name=haproxy_02 --privileged=true haproxy
|
通过浏览器就可以访问haproxy的后端管理界面了 访问:http://192.168.64.136:4001/dbs
输入配置的用户名和密码就可以看到如下界面
测试HAProxy
访问代理WEB端口
访问代理的 5000 端口刷新多次发现正常访问
http://192.168.64.136:5000/
停止主节点
1
| docker stop rabbitmqCluster01
|
代理端口访问WEB端没有影响
springboot 连接测试
修改配置文件地址为 ha代理地址
1 2 3 4 5 6
| spring: rabbitmq: addresses: 192.168.64.136:5010,192.168.64.136:5011 username: guest password: guest ......
|
启动服务,能够正常启动
并且能够正常发送和接收消息
1
| 2020-10-14 14:57:08.060 INFO 14800 --- [ntContainer#0-1] c.heima.rabbitmq.consumer.QueueConsumer : 接收到消息:messageTest
|
小结
上述我们通过HAProxy来代理我们的RabbitMQ集群,我们解决了RabbitMQ集群节点宕机和负载均衡的问题,但是我们所有的服务都连接到了192.168.64.136机器上的HAProxy服务上了,那么如果该机器宕机,或者HAProxy服务挂了,那么整个服务就会直接瘫痪了,即存在单点故障。
那么我们如何来解决HAProxy服务的单点故障问题呢?这里我们可以利用Keepalived和HAProxy来结合起来,构建一个双机热备来保证其高可用。
搭建keepalived
首先看下RabbitMQ高可用负载均衡集群长什么样子:
keepalived的实现是要在docker服务内创建,最后宿主机中也要创建实现docker内外的连接;
为什么使用keepalived
为什么要用keepalived+haproxy实现docker下的高可用负载均衡?在不同环境下有哪些方式可以实现高可用负载均衡?
首先第一点,实现负载均衡并不是只有haproxy一个中间件,网上还有很多方案是用keepalived+LVS等等,所以对于docker下的高可用负载均衡不一定只有keepalived+haproxy。
为什么这里强调的是docker、keepalived?
首先我们运行环境是docker,keepalived的作用是抢占虚拟ip,docker环境下,镜像内的网段外网是无法访问的,所以我们需要一个外网在宿主机上映射到docker内的ip上,keepalived一方面可以映射ip到docker服务内,二可以在docker服务内强占虚拟ip。所以在docker搭建负载均衡的多种方案中都常见会出现keepalived。
为什么要抢占虚拟ip?为什么要用keepalived呢?
负载均衡中间件(haproxy,lvs)等等在实际中不可能只是单节点存在(单节点不需要keepalived),都要有冗余设计,即集群设计,和数据库集群不一样的是,docker中实现负载均衡中间件的集群是通过抢占一个ip地址实现的,有主备和主主方式,虽然方式不一样,但都有一个心跳检测的共同点,在主节点抢占虚拟ip时,主从节点上会有心跳检测线,如果发现主节点心跳检测连不上,则从节点会主动抢占ip实现数据不中断的冗余机制;
总结描述:由于是在docker环境下,我们要搭建负载均衡集群需要通过keepalived抢占虚拟ip实现,而负载均衡功能需要haproxy中间件实现,所以本次我搭建的是一个在docker环境下高可用的负载均衡方案是:keepalived+haproxy。
docker安装keepalived
docker服务内创建,我们需要进入到该服务并安装keepalived
安装keepalived
进入docker-haproxy服务
1
| docker exec -ti haproxy_01 /bin/bash
|
更新update
安装keepalived
1
| apt-get install keepalived
|
安装ifconfig命令 安装ping
1 2
| apt-get install net-tools apt-get install iputils-ping
|
创建配置文件
创建keepalived的配置文件
1
| vi /tmp/etc/keepalived/keepalived.conf
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| vrrp_instance VI_1 {
state MASTER interface eth0 virtual_router_id 100 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 123456 } virtual_ipaddress { 172.18.0.100 } }
|
如果没有安装vi 可以在宿主机编辑好配置文件后复制到docker容器
1
| docker cp /tmp/etc/keepalived/keepalived.conf 4954707572d4:/etc/keepalived
|
启动keepalived
1
| service keepalived start
|
检查配置是否正确
在安装keepalived的docker容器检查是否绑定了eth0网卡,出现如下内容说明绑定成功
在宿主机ping该IP,如果能够ping通说明keepalived已经正常运行了
后续操作
第二个keepalived的配置文件和第一个配置文件完全一样,如果想要分配不同的权重比列,只需要更改权重参数就可以了。
宿主机中keepalived
最后,本地宿主机安装keepalived进行外网路由
安装keepalived
1
| yum install -y keepalived
|
配置keepalived配置文件
进入宿主机/etc/keepalived
目录,编辑keepalived.conf文件内容
1
| vi /etc/keepalived/keepalived.conf
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| vrrp_instance VI_1 { state MASTER
interface ens33 virtual_router_id 100 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress {
192.168.64.150 } }
virtual_server 192.168.64.150 8888 { delay_loop 3 lb_algo rr lb_kind NAT persistence_timeout 50 protocol TCP
real_server 172.18.0.100 8888 { weight 1 } }
virtual_server 192.168.64.150 15672 { delay_loop 3 lb_algo rr lb_kind NAT persistence_timeout 50 protocol TCP
real_server 172.18.0.100 5000 { weight 1 } }
virtual_server 192.168.64.150 5672 { delay_loop 3 lb_algo rr lb_kind NAT persistence_timeout 50 protocol TCP
real_server 172.18.0.100 5010 { weight 1 } }
|
启动宿主机keepalived
配置完后,通过命令service keepalived start启动宿主机的KP,通过ip addr查看网卡中是否出现定义的150 IP地址,如果没有出现大多数是配置文件不正确。
1
| service keepalived start
|
通过ping 150ip地址,发现能够ping通
切换到windows上,进入cmd ping宿主机150的ip地址发现能ping通,通过浏览器输入 http://192.168.64.150:8888/dbs
进入到监听页面:
防火墙配置
在此如果cmd能ping通150 ip 而网页无法进入监听界面,问题出现在防火墙上,centos7默认防火墙是没有开启开启vrrp 协议,而keepalived用的是vrrp协议,所以要么让防火强开通vrrp协议
1 2 3 4 5 6
| firewall-cmd --direct --permanent --add-rule ipv4 filter INPUT 0 --in-interface ens33 --destination 224.0.0.18 --protocol vrrp -j ACCEPT
firewall-cmd --direct --permanent --add-rule ipv4 filter OUTPUT 0 --out-interface ens33 --destination 224.0.0.18 --protocol vrrp -j ACCEPT firewall-cmd --reload
firewall-cmd --reload
|
或者直接关闭防火墙
1
| systemctl stop firewalld.service
|
以上防火墙命令只针对于centos7的firewalld,其他防火墙或者linux版本可以自行百度让vrrp协议能够使用即能让网页进入到监听界面。
docker-compose 任务编排
编写docker-compose.yml
内容如下,注意haproxy和keepalived配置文件同上
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
| version: '2' services: rabbitMQ01: image: rabbitmq:management hostname: rabbitMQ01 container_name: rabbitMQ01 extra_hosts: - "rabbitMQ02:172.18.0.3" - "rabbitMQ03:172.18.0.4" networks: rabbitmq_net: ipv4_address: 172.18.0.2 environment: RABBITMQ_ERLANG_COOKIE: rabbitmqCookie RABBITMQ_NODE_NAME: rabbit@rabbitMQ01 ports: - "5672:5672" - "15672:15672" rabbitMQ02: image: rabbitmq:management hostname: rabbitMQ02 container_name: rabbitMQ02 extra_hosts: - "rabbitMQ01:172.18.0.2" - "rabbitMQ03:172.18.0.4" networks: rabbitmq_net: ipv4_address: 172.18.0.3 depends_on: - rabbitMQ01 environment: RABBITMQ_ERLANG_COOKIE: rabbitmqCookie RABBITMQ_NODE_NAME: rabbit@rabbitMQ02 ports: - "5673:5672" - "15673:15672" rabbitMQ03: image: rabbitmq:management hostname: rabbitMQ03 container_name: rabbitMQ03 extra_hosts: - "rabbitMQ01:172.18.0.2" - "rabbitMQ02:172.18.0.3" networks: rabbitmq_net: ipv4_address: 172.18.0.4 depends_on: - rabbitMQ01 environment: RABBITMQ_ERLANG_COOKIE: rabbitmqCookie RABBITMQ_NODE_NAME: rabbit@rabbitMQ03 ports: - "5674:5672" - "15674:15672" haproxy_01: image: haproxy container_name: haproxy01 privileged: true volumes: - "/tmp/etc/haproxy/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg" - "/tmp/etc/keepalived/keepalived.conf:/etc/keepalived/keepalived.conf" networks: rabbitmq_net: ipv4_address: 172.18.0.5 depends_on: - rabbitMQ01 - rabbitMQ02 - rabbitMQ03 ports: - "4001:8888" - "5000:5000" - "5010:5010" haproxy_02: image: haproxy container_name: haproxy02 privileged: true volumes: - "/tmp/etc/haproxy/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg" - "/tmp/etc/keepalived/keepalived.conf:/etc/keepalived/keepalived.conf" networks: rabbitmq_net: ipv4_address: 172.18.0.6 depends_on: - rabbitMQ01 - rabbitMQ02 - rabbitMQ03 ports: - "4002:8888" - "5001:5000" - "5011:5010" networks: rabbitmq_net: ipam: config: - subnet: 172.18.0.0/16 gateway: 172.18.0.1
|
编写初始化脚本
1
| vi init_rarabbitmq_cluster.sh
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| #!/bin/bash
#reset first node echo "Reset first rabbitmq node." #docker exec rabbitMQ01 /bin/bash -c 'rabbitmqctl stop_app' #docker exec rabbitMQ01 /bin/bash -c 'rabbitmqctl reset' #docker exec rabbitMQ01 /bin/bash -c 'rabbitmqctl start_app'
#build cluster echo "开始将rabbitMQ02节点加入到rabbitMQ01集群节点..." docker exec rabbitMQ02 /bin/bash -c 'rabbitmqctl stop_app' docker exec rabbitMQ02 /bin/bash -c 'rabbitmqctl reset' docker exec rabbitMQ02 /bin/bash -c 'rabbitmqctl join_cluster --ram rabbit@rabbitMQ01' docker exec rabbitMQ02 /bin/bash -c 'rabbitmqctl start_app'
echo "开始将rabbitMQ03节点加入到rabbitMQ01集群节点..." docker exec rabbitMQ03 /bin/bash -c 'rabbitmqctl stop_app' docker exec rabbitMQ03 /bin/bash -c 'rabbitmqctl reset' docker exec rabbitMQ03 /bin/bash -c 'rabbitmqctl join_cluster --ram rabbit@rabbitMQ01' docker exec rabbitMQ03 /bin/bash -c 'rabbitmqctl start_app'
#check cluster status echo "检查rabbitMQ01集群节点状态..." docker exec rabbitMQ01 /bin/bash -c 'rabbitmqctl cluster_status' echo "检查rabbitMQ02集群节点状态..." docker exec rabbitMQ02 /bin/bash -c 'rabbitmqctl cluster_status' echo "检查rabbitMQ03集群节点状态..." docker exec rabbitMQ03 /bin/bash -c 'rabbitmqctl cluster_status'
# haproxy 安装keepalived echo "开始在haproxy01安装..." docker exec haproxy01 /bin/bash -c 'apt-get -y update&&apt-get install -y keepalived net-tools iputils-ping' echo "开始在haproxy02安装..." docker exec haproxy02 /bin/bash -c 'apt-get -y update&&apt-get install -y keepalived net-tools iputils-ping'
# 启动 keepalived echo "开始启动keepalived..." docker exec haproxy01 /bin/bash -c 'service keepalived start' docker exec haproxy02 /bin/bash -c 'service keepalived start'
|
配置文件配置
HAProxy配置参考上面配置
keepalived配置参考上面配置
宿主机中keepalived
参考上面配置
启动容器
执行初始化脚本
1
| sh init_rarabbitmq_cluster.sh
|
访问测试
能够访问说明高可用已经搭建成功