RabbitMQ高可用集群
搞笑开心一下
2021年04月21日 11:12

RabbitMQ是用Erang开发的,集群非常方便,因为Erlang天生就是一门分布式语言,但其本身并不支持负载均衡。

一. 集群特点

RabbitMQ的集群节点包括内存节点、磁盘节点。内存节点将所有的队列,交换器,绑定关系,用户,权限,和vhost的元数据信息保存在内存中。磁盘节点将这些信息保存在磁盘中,但是内存节点的性能更高,为了保证集群的高可用性,必须保证集群中有两个以上的磁盘节点,来保证当有一个磁盘节点崩溃了,集群还能对外提供访问服务. 所以最合适的方案就是既有多内存节点,又有双磁盘节点。

二.RabbitMQ集群架构

主备模式

实现RabbitMQ的高可用集群,一般在并发和数据量不高的情况下,这种模式非常的好且简单。主备模式也称为Warren模式

主备模式:就是warren(兔子窝)模式,就是一个主/备方案(主节点如果挂了,从节点提供服务而已,和activemq利用zookeeper做主/备一样)

HAProxy是一个使用C语言编写的自由及开放源代码软件,其提供高可用性、负载均衡,以及基TCP和HTTP的应用程序代理。

   HAProxy特别适用于那些负载特大的web站点, 完全可以支持数以万计的并发连接.同时可以保护web服务器不被暴露到网络上。

远程模式

远程模式:远距离通信和复制,所谓Shovel就是我们可以把消息进行不同数据中心的复制工作,我们可以跨地域的让两个MQ集群互联。 分摊服务器压力,并且在使用了shovel插件后,模型变成了近端同步确认远端异步确认方式,大大提高了消息确认速度,并且还能保证可靠性。

镜像模式(常用)

镜像模式:集群模式非常经典的就是Mirror镜像模式,保证100%数据不丢失,在实际工作中用的最多的。并且实现集群非常的简单,一般互联网大厂都会构建这种镜像集群模式。

Mirror镜像队列,目的是为了保证rabbitmq数据的高可靠性解决方案,主要就是实现数据的同步,一般来讲是2-3个实现数据同步(对于100%数据可靠性解决方案一般是3个节点)集群架构如下:

Keepalived的作用是检测服务器的状态,如果有一台web服务器宕机,或工作出现故障,Keepalived将检测到,并将有故障的服务器从系统中剔除,同时使用其他服务器代替该服务器的工作,当服务器工作正常后Keepalived自动将服务器加入到服务器群中,这些工作全部自动完成,不需要人工干涉,需要人工做的只是修复故障的服务器。 

多活模式

多活模式:这种模式也是实现异地数据复制的主流模式,因为Shovel模式配置比较复杂,所以一般来说实现异地集群都是使用双活或者多活模式来实现的。这种模式需要依赖rabbitmq的federation插件,可以实现继续的可靠AMQP数据通信,多活模式在实际配置与应用非常的简单。

RabbitMQ部署架构采用双中心模式(多中心),那么在两套(或多套)数据中心中各部署一套RabbitMQ集群,各中心之间还需要实现队列消息共享。多活集群架构如下

3. 集群搭建

环境准备

注意,RabbitMQ集群节点必须在同一网段里,如果是跨广域网,效果会变差。

配置hosts文件

更改三台MQ节点的计算机名分别为mq01、mq02 和mq03,然后修改hosts配置文件

代码块
JavaScript
自动换行
复制代码
vi /etc/hostname    //其他两台相同
mq01.localdomain

vi /etc/hosts //注意不能带.注意-主机名称也要更改
192.168.25.128 mq01  
192.168.25.129 mq02
192.168.25.130 mq03
复制成功

注意:改完后重启服务器即可生效.

拷贝 .erlang.cookie

Rabbitmq的集群是依附于erlang的集群来工作的,所以必须先构建起erlang的集群。Erlang的集群中各节点是经由过程一个magic cookie来实现的,这个cookie存放在/var/lib/rabbitmq/.erlang.cookie中,文件是400的权限。所以必须保证各节点cookie一致,不然节点之间就无法通信。

代码块
JavaScript
自动换行
复制代码
// 查看cookie值
cat /var/lib/rabbitmq/.erlang.cookie
复制成功

用scp的方式将mq01节点的.erlang.cookie的值复制到其他两个节点中。

代码块
JavaScript
自动换行
复制代码
// 复制到mq02
scp /var/lib/rabbitmq/.erlang.cookie root@192.168.25.129:/var/lib/rabbitmq/.erlang.cookie
// 复制到mq03
scp /var/lib/rabbitmq/.erlang.cookie root@192.168.25.130:/var/lib/rabbitmq/.erlang.cookie
复制成功

如果出现这个错误这对每台服务器关闭防火墙即可

代码块
JavaScript
自动换行
复制代码
systemctl stop firewalld.service
复制成功

分别启动mq01/mq02/mq03 rabbitmq服务

代码块
JavaScript
自动换行
复制代码
service rabbitmq-server start
复制成功

将mq02、mq03作为内存节点加入mq01节点集群中

代码块
JavaScript
自动换行
复制代码
rabbitmqctl stop_app    //停掉rabbit应用

rabbitmqctl join_cluster --ram rabbit@mq01 //加入到磁盘节点

rabbitmqctl start_app  //启动rabbit应用
复制成功

(1)默认rabbitmq启动后是磁盘节点,在这个cluster命令下,mq02和mq03是内存节点,mq01是磁盘节点。

(2)如果要使mq02、mq03都是磁盘节点,去掉--ram参数即可。

(3)如果想要更改节点类型,可以使用命令rabbitmqctl change_cluster_node_type disc(ram),前提是必须停掉rabbit应用

登录rabbitmq web管理控制台

创建新的队列会同步其他节点,在RabbitMQ集群集群中,必须至少有一个磁盘节点,否则队列元数据无法写入到集群中,当磁盘节点宕掉时,集群将无法写入新的队列元数据信息。

4.镜像队列

上面已经完成RabbitMQ默认集群模式,但并不保证队列的高可用性,尽管交换机、绑定这些可以复制到集群里的任何一个节点,但是队列内容不会复制。虽然该模式解决一项目组节点压力,但队列节点宕机直接导致该队列无法应用,只能等待重启,所以要想在队列节点宕机或故障也能正常应用,就要复制队列内容到集群里的每个节点,必须要创建镜像队列。镜像队列是基于普通的集群模式的,然后再添加一些策略,所以你还是得先配置普通集群,然后才能设置镜像队列,我们就以上面的集群接着做。

创建rabbitmq策略

在mq01节点的控制台上创建策略

  1. 点击admin菜单–>右侧的Policies选项–>左侧最下下边的Add/update a policy。

  2. 按照图中的内容根据自己的需求填写

  • Name:策略名称

  • Pattern:匹配的规则,如果是匹配所有的队列,那就是^.

  • Definition:使用ha-mode模式中的all,也就是同步所有匹配的队列。问号链接帮助文档。

3. 点击Add policy添加策略

此时分别登陆mq02、mq03两个节点的控制台,可以看到上面添加的这个策略,如图所示:

创建消息

点击test队列发布消息

做破坏性测试

  1. 将mq01节点的服务关闭,再通过mq02和mq03查看消息记录是否还存在。

代码块
JavaScript
自动换行
复制代码
rabbitmqctl stop_app  //停掉mq01的rabbit应用
复制成功

从中可以看到test队列已经从之前的+2显示成+1了,而且消息记录是存在的。

2. 再将mq02节点的服务关闭,通过mq03查看消息记录是否还存在。

代码块
JavaScript
自动换行
复制代码
rabbitmqctl stop_app  //停掉mq02的rabbit应用
复制成功

3. 将mq01和mq02的服务再启动起来

代码块
JavaScript
自动换行
复制代码
rabbitmqctl start_app   //启动mq01、mq02的rabbit应用
复制成功

从中可以看到ab队列后面+2变成了粉色,鼠标指上去显示镜像无法同步。如果这时候停掉mq03节点的服务,那么队列里面的消息将会丢失。

采取的解决办法是选择在mq01或者mq02节点上执行同步命令。

代码块
JavaScript
自动换行
复制代码
rabbitmqctl sync_queue test  //同步test队列
复制成功

这样,我们就测试了rabbitmq集群的破坏性测试,说明集群配置成功。

三. Haproxy负载代理

利用haproxy做负载均衡

环境

安装

1. 安装haproxy

代码块
JavaScript
自动换行
复制代码
yum install haproxy
复制成功

2.编辑配置文件

代码块
JavaScript
自动换行
复制代码
vi /etc/haproxy/haproxy.cfg
复制成功

3.在配置文件中添加内容

代码块
JavaScript
自动换行
复制代码
#配置haproxy mq监控
listen rabbitmq_local_cluster 0.0.0.0:5672 
    #配置TCP模式 
    mode tcp
    option tcplog 
    #简单的轮询 
    balance roundrobin  
    #rabbitmq集群节点配置 
    server rabbit1 192.168.25.128:5672 check inter 5000 rise 2 fall 2 
    server rabbit2 192.168.25.129:5672 check inter 5000 rise 2 fall 2 
    server rabbit3 192.168.25.130:5672 check inter 5000 rise 2 fall 2
#配置haproxy web监控,查看统计信息 
listen private_monitoring :8100 
    mode http 
    option httplog 
    stats enable 
    #设置haproxy监控地址为http://IP:8100/stats 
    stats uri /stats 
    stats refresh 30s 
    #添加用户名密码认证
    stats auth admin:1234
#配置haproxy mqweb监控,查看管理控制台
listen rabbitmq_web_local_cluster 0.0.0.0:15672 
    #配置HTTP模式 
    mode http
    option httplog 
    #简单的轮询 
    balance roundrobin  
  #rabbitmq集群节点配置 
    server web_rabbit1 192.168.25.128:15672 check inter 5000 rise 2 fall 2 
    server web_rabbit2 192.168.25.129:15672 check inter 5000 rise 2 fall 2 
    server web_rabbit3 192.168.25.130:15672 check inter 5000 rise 2 fall 2
复制成功

4.启动

代码块
JavaScript
自动换行
复制代码
haproxy -f /etc/haproxy/haproxy.cfg
复制成功

5.启动成功后访问不了请关闭防火墙

代码块
JavaScript
自动换行
复制代码
systemctl stop firewalld.service 
复制成功

五.keepalived检测

分别在两台ha主机上安装keepalived

安装

1.安装keepalived

代码块
JavaScript
自动换行
复制代码
yum install keepalived
复制成功

2.编辑配置文件

代码块
JavaScript
自动换行
复制代码
vi /etc/keepalived/keepalived.conf
复制成功

3.主-文件内容

代码块
JavaScript
自动换行
复制代码
! Configuration File for keepalived
# 全局配置,配置收件人
global_defs {
   notification_email {               ##通知机制,收件人
     boxuegu@qq.com
   }
   notification_email_from keepalived@domain.com ####发件人
   smtp_server 192.168.25.125                    ##发件服务器
   smtp_connect_timeout 30                       ##服务器连接超时时间
   router_id LVS_DEVEL                           ##路由器标志
}
# 集群资源监控,组合track_script进行
vrrp_script check_haproxy {
	script "killall -0 haproxy"
	interval 2
}
vrrp_instance HAPROXY_HA {
	# 设置当前主机为主节点,如果是备用节点,则设置为BACKUP
	# 备用节点时,设置为:
	# state BACKUP
	state MASTER
	# 指定HA监测网络接口,可以用ifconfig查看来决定设置哪一个
	interface ens33
	# 虚拟路由标识,同一个VRRP实例要使用同一个标识,主备机
	virtual_router_id 80
	# 因为当前环境中VRRP组播有问题,改为使用单播发送VRRP报文
	# 这个地方需要关注,之前未做此设置,结果主备节点互相不能发现,因此主备节点都升级成了MASTER,并且绑定了VIP
	# 主节点时,内容为:
	unicast_src_ip 192.168.25.125
	 unicast_peer {
	 192.168.25.126
	}
	# 备节点时,内容为:
	#unicast_src_ip 192.168.25.126
	#unicast_peer {
	#192.168.25.125
	#}
	# 设置优先级,确保主节点的优先级高过备用节点
	# 主节点时,设置为:
	priority 100
	# 备节点时,设置为:
	#priority 80
	# 用于设定主备节点间同步检查时间间隔
	advert_int 2
	# 设置高可用集群中不抢占功能,在主机down后,从机接管,当主机重新恢复后,设置此功能,备机将继续提供服务,从而避免因切换导致的隐患
	nopreempt
	# 设置主备节点间的通信验证类型及密码,同一个VRRP实例中需一致
	authentication {
		auth_type PASS
		auth_pass 1234
	}
	#下面这些脚本都是写入日志,需要的话可以打开,自己写一个shell
	# 当keepalived切换状态到MASTER时,执行脚本
	#notify_master "/etc/keepalived/master.sh"
	# 当keepalived切换状态到BACKUP时,执行脚本
	#notify_backup "/etc/keepalived/backup.sh"
	# 当keepalived切换状态到FAULT时,执行脚本
	#notify_fault "/etc/keepalived/fault.sh"
	# 当keepalived切换状态到STOP时,执行脚本
	#notify_fault "/etc/keepalived/stop.sh"
	# 集群资源监控,组合vrrp_script进行
	track_script {
		check_haproxy
	}
	# 设置虚拟IP地址,当keepalived状态切换为MASTER时,此IP会自动添加到系统中
	# 当状态切换到BACKUP时,此IP会自动从系统中删除
	# 可以通过命令ip add查看切换后的状态
	virtual_ipaddress {
		192.168.25.110  #虚拟ip配置完之后就用它访问
	}

}
复制成功

4.备-文件内容

代码块
JavaScript
自动换行
复制代码
! Configuration File for keepalived
# 全局配置,配置收件人
global_defs {
   notification_email {               ##通知机制,收件人
     boxuegu@qq.com
   }
   notification_email_from keepalived@domain.com ####发件人
   smtp_server 192.168.25.126                     ##发件服务器
   smtp_connect_timeout 30                       ##服务器连接超时时间
   router_id LVS_DEVEL                           ##路由器标志
}
# 集群资源监控,组合track_script进行
vrrp_script check_haproxy {
	script "killall -0 haproxy"
	interval 2
}
vrrp_instance HAPROXY_HA {
	# 设置当前主机为主节点,如果是备用节点,则设置为BACKUP
	# 备用节点时,设置为:
	state BACKUP
	# 指定HA监测网络接口,可以用ifconfig查看来决定设置哪一个
	interface ens33
	# 虚拟路由标识,同一个VRRP实例要使用同一个标识,主备机
	virtual_router_id 80
	# 因为当前环境中VRRP组播有问题,改为使用单播发送VRRP报文
	# 这个地方需要关注,之前未做此设置,结果主备节点互相不能发现,因此主备节点都升级成了MASTER,并且绑定了VIP
	# 备节点时,内容为:
	unicast_src_ip 192.168.25.126
	unicast_peer {
	192.168.25.125
	}
	# 设置优先级,确保主节点的优先级高过备用节点
	# 备节点时,设置为:
	priority 80
	# 用于设定主备节点间同步检查时间间隔
	advert_int 2
	# 设置高可用集群中不抢占功能,在主机down后,从机接管,当主机重新恢复后,设置此功能,备机将继续提供服务,从而避免因切换导致的隐患
	nopreempt
	# 设置主备节点间的通信验证类型及密码,同一个VRRP实例中需一致
	authentication {
		auth_type PASS
		auth_pass 1234
	}
	#下面这些脚本都是写入日志,需要的话可以打开,自己写一个shell
	# 当keepalived切换状态到MASTER时,执行脚本
	#notify_master "/etc/keepalived/master.sh"
	# 当keepalived切换状态到BACKUP时,执行脚本
	#notify_backup "/etc/keepalived/backup.sh"
	# 当keepalived切换状态到FAULT时,执行脚本
	#notify_fault "/etc/keepalived/fault.sh"
	# 当keepalived切换状态到STOP时,执行脚本
	#notify_fault "/etc/keepalived/stop.sh"
	# 集群资源监控,组合vrrp_script进行
	track_script {
		check_haproxy
	}
	# 设置虚拟IP地址,当keepalived状态切换为MASTER时,此IP会自动添加到系统中
	# 当状态切换到BACKUP时,此IP会自动从系统中删除
	# 可以通过命令ip add查看切换后的状态
	virtual_ipaddress {
		192.168.25.110  #虚拟ip配置完之后就用它访问
	}

}
复制成功

5.启动

代码块
JavaScript
自动换行
复制代码
systemctl start keepalived.service
复制成功

6.查看是否启动成功

代码块
JavaScript
自动换行
复制代码
ps -ef | grep keepalived
复制成功