首先我们要了解RabbitMQ的集群架构模式,比如主备、shovels、镜像集群队列、异步多集群
然后从0开始构建一个异步的镜像队列集群,然后整合HAProxy和keepalive,实现高可用、高可靠。
然后我们来讲解下配置文件中的一些关键配置的含义和推荐配置。
j接下来我们来看看运维工作,结合场景来理解下恢复和失败转移的5种方案。
https://www.rabbitmq.com/distributed.html#overview
有三种方法可以实现RMQ的分布式:集群、联邦、Shovel插件。请注意,这三种方法并不是相互排斥的,可以组合使用:集群可以通过Federation或Shovel连接在一起,以获得更高的灵活性。
集群节点可以帮助提高队列内容的可用性和数据安全性,并维持更多的并发客户机连接。集群、仲裁队列和经典镜像队列指南提供了有关这些主题的更多细节。
虚拟主机,交换机,用户和权限会在所有节点间共享,队列可以位于单个节点上,或者同步到其他节点以实现HA,仲裁队列是一种关注安全的多副本队列。经典队列可以选择是否做镜像。
连接到集群中任何节点的客户机可以使用集群中的所有非独占队列,即使它们不在该节点上。
联邦机制允许一个broker上的交换机或者队列接收其他broker上交换机或者队列发布的消息(这个broker可以是单独的机器或者其他集群上的)。通过AMQP(SSL可选),如果2个交换机或者队列通过联邦机制连接,比如设置相应的用户和权限。
联邦exchange是用单向的点对点链接连接的。默认情况下,消息将只在联合链接上转发一次,但可以增加转发次数,以适应更复杂的路由拓扑。有些消息可能不会通过该链接转发;如果消息到达联邦exchange后没有被路由到队列,那么它一开始就不会被转发。
联邦队列会简单的通过单向的点对点连接,消息会跟随消费者在联邦队列之间移动任意次。
通常,你可以使用联邦机制在internet 上通过广播和工作队列来连接broker。
使用Shovel插件连接broker在概念上与使用Federation机制连接broker相似。然而,插件工作在一个较低的级别。
federation的目的是为交换和队列提供严格的(opinionated )分布,而shovel只是简单地从一个broker上的queue中获取消息,并将其转发给另一个broker上的exchange。
通常,如果你需要比联邦机制更多的控制,你会使用shovel去连接brokers。
动态Shovel用于在单个代理上以特别的方式移动消息。
Federation and/or Shovel | Clustering |
---|---|
Brokers在逻辑上是隔离的,会有不同的owner | 逻辑上是单个Broker节点 |
broker可以运行不同版本的RabbitMQ和Erlang(在某些方面是不兼容的)。 | 所有节点必须运行在匹配的RabbitMQ和Erlang |
各个Broker节点可以通过广域网互连,当然要先授予适当的用户和权限 | Broker必须通过合理可靠可信任的局域网连接。通过Erlang内部节点传递消息,但节点间要有相同的Erlang cookie |
Broker以任何拓扑连接。链接可以是单向的,也可以是双向的。 | 节点之间的链接都是双向的 |
从CAP理论中选择可用性和分区耐受性,即AP | 从CAP理论中选择一致性和可用性,CA |
代理中的一些交换可能是基于Federation的,而另一些可能是本地的。 | 集群中所有Broker节点中的交换机都是一样的,要么全有要么全无 |
客户端能看到它所连接的Broker节点上的队列 | 客户端连接到及群众任何节点的客户机可以在所有节点的非独占队列。 |
如图为主备模式的简单架构模型,主要是利用HaProxy
去做的主备切换,当主节点挂掉时,HaProxy
会自动进行切换,把备份节点升级为主节点
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pbcZE15G-1617066262538)(RabbitMQ1.assets/14795543-cb22a5c135be9073.png)]
HAProxy 是一款提供高可用性、负载均衡以及基于TCP(第四层)和HTTP(第七层)应用的代理软件,需要进行配置
listen rabbitmq_cluster
#配置tcp模式
bind 0.0.0.0:5672
#简单的轮询
mode tcp
#主节点
balance roundrobin
#inter 每隔5秒对mq集群做健康检查
# inter每隔五秒对mq集群做健康检查,2次正确证明服务器可用,3次失败证明服务器不可用,并且配置主备机制
#rise 2次正确证明服务器可用
#fall 2次失败证明服务器不可用,并且配置主备机制
server rbq1 192.168.10.101:5672 check inter 5000 rise 2 fall 3
#备用节点
server rbq2 192.168.10.102:5672 backup check inter 5000 rise 2 fall 3
远程模式:远距离通信和复制,可以实现双活的一种模式,简称Shovel模式。我们可以把消息进行不同数据中心的复制工作,我们可以跨地域的让多个mq集群互联。
Shovel架构模型:绿色部分就代表了两个不同地域的MQ节点,假设用户在A地方下一个订单,然后订单投递到了MQ,第一个地方的MQ节点为了避免压力过大、负载过高可以设置一个阈值,如果负载过高将订单信息转到另一个地方的MQ,分摊服务压力。同时也可以进行两个或多个中心的数据同步。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vNwZROgI-1617066262540)(RabbitMQ1.assets/14795543-51e02588c0c7973d.jpg)]
好处:在使用了shovel插件后,模型变成了近端同步确认,远端异步确认的方式,大大提高了订单确认速度,并且还能保证可靠性
Shovel集群的拓扑图如下所示 ,一个订单进来之后,里面有两个队列,如果正常队列压力过大,会将订单路由到右边的backup队列,这个backup队列和另一个地域的MQ(某个交换机)产生了Shovel联系,就会把数据复制到远端MQ中心,在远端会有相应的队列进行消费
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rwrIoYrk-1617066262542)(RabbitMQ1.assets/14795543-460a5db89f698889.jpg)]
Shovel集群的配置,首先启动rabbitmq插件,命令如下:
rabbitmq-plugins enable amqp_client
rabbitmq-plugins enable rabbitmq_shovel
创建rabbitmq.config文件:touch /etc/rabbitmq/rabbitmq.config
在config文件中添加相关的配置
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-e5CTYRns-1617066262543)(file://E:/teach/0804RabbitMQ/%E8%A1%A5%E5%85%85%EF%BC%9A10.RabbitMQ/10.RabbitMQ1.assets/Snipaste_2020-06-01_16-04-25-1615512791511.png?lastModify=1615512787)]
主要是来源和目的地的设置,2个地址设置好后还要设置公共的routing key,如果A中心的压力过大,想要转移到B中心,这个routing key如何去指定。下面是ACK的模式,
最后我们需要源服务器和目的地服务器都使用相同的配置文件(rabbitmq.config)
事实上这个配置会相对复杂一些,实现双活已经有更好的方式,所以远程模式了解即可。
红色的虚线框就是镜像队列的集群
黄色的就是应用服务器,里面红色的部分包含了RabbitMQ节点,节点里面有个Mirror queue
,这三个镜像队列数据是要同步的。
前端用keepavlived做负载均衡,因为应用的连接可能连接3个节点的任意一个,那为什么要用到keepavlived呢,因为我们要做多个HA-proxy,比如一个HA-proxy挂了,我们虚拟的对外ip会飘移到另外的一个蓝色节点继续提供服务。
外部发送一条消息,落到一台服务器上,这台服务器将数据进行同步,同步到另外两个节点上。
利用HA-proxy
做负载均衡,然后KeepAlived
做多个HA-proxy的高可用切换
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-g8v7xzrm-1617066262544)(RabbitMQ1.assets/14795543-853fa98d8d0282ff.jpg)]
federation
插件,可以实现持续的可靠的AMQP数据通信,多活模式在实际配置与应用上非常的简单。上层就是应用层,然后经过LBS负载均衡,两套RabbitMQ集群,可能是两套镜像队列,两套集群通过federation插件进行数据的复制和流转。
federation插件不是建立在集群上的,而是建立到单个节点上,比如左边node3可以和右边任意一台建立这种多活机制,然后,自己这边的集群如果是采用镜像队列那么也会在自己集群内部去进行同步,所以这种性能也是非常好的。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-R8VkIQpp-1617066262545)(RabbitMQ1.assets/14795543-dcb47808c4abb0e1.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-f5DTu74I-1617066262546)(RabbitMQ1.assets/14795543-f38fbe2d746d9fb7.jpg)]
upstream是上游,上下游之间要建立一个link
如图所示上游服务和下游服务,建立一个Link连接,可以认为就是federation,X代表Exchange
上游过来的数据,可以通过Exchange,直接转到下游,下游Exchange去接收数据,然后路由到具体的队列进行消费。
上游过来的数据不是说所有的数据都会流转到下游的,而是说建立对应关系,下游需要有具体的队列进行存储。
上游也可以自己去监听,同一个数据可以发到两个集群中,都可以用队列去接收存储然后消费。
一共5台节点,3台搭建集群,2台作为HA-proxy和keepalived。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PMWgWgCM-1617066262547)(RabbitMQ1.assets/image-20210312100746202.png)]
3个节点都安装RMQ
3个节点都停止RMQ服务
rabbitmqctl stop
文件同步
PS:选择76、77、78任意一个节点为Master(这里选择76为Master),也就是说我们需要把76的Cookie文件同步到77、78节点上去,进入/var/lib/rabbitmq目录下,把/var/lib/rabbitmq/.erlang.cookie文件的权限修改为777,原来是400;然后把.erlang.cookie文件copy到各个节点下;最后把所有cookie文件权限还原为400即可。
/etc/init.d/rabbitmq-server stop
//进入目录修改权限;远程copy77、78节点,比如:
scp /var/lib/rabbitmq/.erlang.cookie 到192.168.11.77和192.168.11.78的var/lib/rabbitmq/中
组成集群操作
PS:接下来我们就可以使用集群命令,配置76、77、78为集群模式,3个节点(76、77、78)执行启动命令,后续启动集群使用此命令即可。
rabbitmq-server -detached
lsof -i:5672
slave加入集群操作(重新加入集群也是如此,以最开始的主节点为加入节点)
//注意做这个步骤的时候:需要配置/etc/hosts 必须相互能够寻址到
bhz77:rabbitmqctl stop_app
bhz77:rabbitmqctl join_cluster --ram rabbit@bhz76
bhz77:rabbitmqctl start_app
bhz78:rabbitmqctl stop_app
bhz78:rabbitmqctl join_cluster rabbit@bhz76
bhz78:rabbitmqctl start_app
//在另外其他节点上操作要移除的集群节点
rabbitmqctl forget_cluster_node rabbit@bhz24
修改RabbitMQ集群名称
PS:修改集群名称(默认为第一个node名称):
任意节点执行都可以
rabbitmqctl set_cluster_name rabbitmq_cluster1
查看集群状态
PS:最后在集群的任意一个节点执行命令:查看集群状态
rabbitmqctl cluster_status
管控台界面
PS: 访问任意一个管控台节点,显示的都是集群的信息:http://192.168.11.71:15672 如图所示
配置镜像队列
PS:设置镜像队列策略(在任意一个节点上执行)
rabbitmqctl set_policy ha-all "^" '{"ha-mode":"all"}'
PS:将所有队列设置为镜像队列,即队列和队列的数据会被复制到各个节点,各个节点状态一致,
此时RabbitMQ高可用集群就已经搭建好了,我们可以重启服务,查看其队列是否在从节点同步。
此时查看UI界面,每个队列都会同步到所有节点
listener points变为3
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Zg9Xac90-1617066262547)(RabbitMQ1.assets/image-20210312103020601.png)]
HaProxy是一款提供高可用性、负载均衡以及基于TCP(第四层)和HTTP(第七层)应用的代理软件,支持虚拟主机,它是免费、快速并且可靠的一种解决方案。
HaProxy特别适用于那些负载特大的web站点,这些站点通常又需要会话保持或七层处理。HaProxy运行在时下的硬件上,完全可以支持数以万计的并发连接,并且它的运行模式使得它可以很简单安全的整合进您当前的架构中,同时可以保护你的web服务器不被暴露到网络上
PS:79、80节点同时安装Haproxy,下面步骤统一
//下载依赖包
yum -y install gcc vim wget net-tools
//下载[haproxy](http://www.linuxea.com/tag/haproxy/)
wget http://www.[haproxy](http://www.linuxea.com/tag/haproxy/).org/download/1.6/src/haproxy-1.6.5.tar.gz
//解压 tar -zxvf haproxy-1.6.5.tar.gz -C /usr/local
//进入目录、进行编译、安装
cd /usr/local/haproxy-1.6.5
make TARGET=linux31 PREFIX=/usr/local/haproxy
make install PREFIX=/usr/local/haproxy
mkdir /etc/haproxy
//赋权
groupadd -r -g 149 haproxy
useradd -g haproxy -r -s
/sbin/nologin -u 149 haproxy
//创建haproxy配置文件
touch /etc/haproxy/haproxy.cfg
PS:haproxy 配置文件haproxy.cfg详解
vim /etc/haproxy/haproxy.cfg
#logging options
global
log 127.0.0.1 local0 info
maxconn 5120
chroot /usr/local/haproxy
uid 99
gid 99
daemon
quiet
nbproc 20
pidfile /var/run/haproxy.pid
defaults
log global
#使用4层代理模式,”mode http”为7层代理模式
mode tcp
#if you set mode to tcp,then you nust change tcplog into httplog
option tcplog
option dontlognull
retries 3
option redispatch
maxconn 2000
contimeout 5s
##客户端空闲超时时间为 60秒 则HA 发起重连机制
clitimeout 60s
##服务器端链接超时时间为 15秒 则HA 发起重连机制
srvtimeout 15s
#front-end IP for consumers and producters
listen rabbitmq_cluster
bind 0.0.0.0:5672
#配置TCP模式
mode tcp
#balance url_param userid
#balance url_param session_id check_post 64
#balance hdr(User-Agent)
#balance hdr(host)
#balance hdr(Host) use_domain_only
#balance rdp-cookie
#balance leastconn
#balance source //ip
#简单的轮询
balance roundrobin
#rabbitmq集群节点配置
#inter 每隔五秒对mq集群做健康检查, 2次正确证明服务器可用,2次失败证明服务器不可用,并且配置主备机制
server bhz76 192.168.11.76:5672 check inter 5000 rise 2 fall 2
server bhz77 192.168.11.77:5672 check inter 5000 rise 2 fall 2
server bhz78 192.168.11.78:5672 check inter 5000 rise 2 fall 2
#配置haproxy web监控,查看统计信息
listen stats
bind 192.168.11.79:8100
mode http
option httplog
stats enable
#设置haproxy监控地址为http://localhost:8100/rabbitmq-stats
stats uri /rabbitmq-stats
stats refresh 5s
/usr/local/haproxy/sbin/haproxy -f /etc/haproxy/haproxy.cfg
//查看haproxy进程状态
ps -ef | grep haproxy
PS:访问如下地址可以对rmq节点进行监控:http://192.168.1.27:8100/rabbitmq-stats
此时代理的是3台RabbitMQ节点,绿色表示正常
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YGs9rRFj-1617066262548)(RabbitMQ1.assets/image-20210312104907028.png)]
killall haproxy
ps -ef | grep haproxy
Keepalived,它是一个高性能的服务器高可用或热备解决方案,Keepalived主要来防止服务器单点故障的发生问题,可以通过其与Nginx、Haproxy等反向代理的负载均衡服务器配合实现web服务端的高可用。Keepalived以VRRP协议为实现基础,用VRRP协议来实现高可用性(HA).VRRP(Virtual Router Redundancy Protocol)协议是用于实现路由器冗余的协议,VRRP协议将两台或多台路由器设备虚拟成一个设备,对外提供虚拟路由器IP(一个或多个)。
KeepAlived软件主要是通过VRRP协议实现高可用功能。VRRP是Virtual Router RedundancyProtocol(虚拟路由器冗余协议)的缩写,VRRP出现的目的就是为了解决静态路由单点故障的问题,他能够保证当个别节点宕机时,整个网络可以不间断地运行。KeepAlived以方便具有配置管理LVS的功能,同时还具有对LVS下面节点进行健康检查的功能,另一方面也可以实现系统网络服务的高可用功能
keepalived用来实现集群的高可用,对外提供一个统一vip,然后根据策略将请求转发到某个节点处理。
haproxy和keepalived必须在一台机器里一起部署,不能分开。本质就是ha对rabbitmq的每个broker做负载均衡,而keep对两台ha服务器做高可用,那么既然keep是针对ha,所以必须要把ha和keep放到一起部署才有意义。
通过VRRP协议实现,在KeepAlived服务正常工作时,主节点会不断地向备节点发送(多播方式)心跳小新,用以高速备节点自己还活着,当主节点故障时,就无法发送心跳消息,备节点也因此无法继续检测到来自主节点的心跳,于是调用自身的截关程序,接管主节点的IP资源及服务。当主节点恢复时,备节点又会释放主节点故障时自身接管的IP资源及服务,恢复到原来的备用角色
安装
#两个节点都要安装,使用root用户执行即可
#下载依赖
yum -y install openssl openssl-devel
#解压haproxy
tar -zxvf keepalived-2.0.20.tar.gz -C /usr/local/
#进入目录编译、安装
cd /usr/local/keepalived-2.0.20/
./configure --prefix=/usr/local/keepalived
make && make install
#将keepalived安装成linux服务,因为没有使用keepalived的默认安装路径(默认路径/usr/local)安装完成之后,需要做一些修改工作
#创建文件
mkdir /etc/keepalived
#复制配置文件
cp /usr/local/keepalived/etc/keepalived/keepalived.conf /etc/keepalived
#复制脚本文件
cp /usr/local/keepalived/etc/sysconfig/keepalived /etc/sysconfig
ln -s /usr/local/sbin/keepalived /usr/sbin
#如果存在则进行删除 rm /sbin/keepalived
ln -s /usr/local/keepalived/sbin/keepalived /sbin
#设置开机启动
chkconfig keepalived on
# 2个节点都要创建
vim /etc/keepalived/keepalived.conf
通过一个脚本不断去检查节点是否健康,如果不健康,就去调用haproxy的命令去切换
主从不同的地方就是router_id、state、mcast_src_ip
global_defs{
#标识节点的字符串,通常为hostname
router_id ha1
}
vrrp_script chk_haproxy{
#执行脚本位置
script "/etc/keepalived/haproxy_check.sh"
#检测时间间隔
interval 2
#如果条件成立则权重减20
weight -20
}
vrrp_instance VI_1{
#主节点为MASTER,备节点为BACKUP
state MASTER
#绑定虚拟IP的网络接口(网卡),与本机IP地址所在的网络接口相同
interface ens32
#虚拟路由ID号(主备节点一定要相同)
virtual_router_id 103
#本机ip地址
mcast_src_ip 192.168.233.103
#优先级配置(0-254的值)
priority 100
nopreempt
#组播信息发送间隔,两个节点必须配置一致,默认1s
advert_int 1
#认证匹配,2个keepalived想要组成集群,要靠这个来认证
authentication{
auth_type PASS
auth_pass root #密码
}
track_script{
chk_haproxy
}
virtual_ipaddress{
#外部访问的虚拟ip,可以指定多个
192.168.10.110
}
}
global_defs{
#标识节点的字符串,通常为hostname
router_id ha2
}
vrrp_script chk_haproxy{
#执行脚本位置
script "/etc/keepalived/haproxy_check.sh"
#检测时间间隔
interval 2
#如果条件成立则权重减20
weight -20
}
vrrp_instance VI_1{
#主节点为MASTER,备节点为BACKUP
state BACKUP
#绑定虚拟IP的网络接口(网卡),与本机IP地址所在的网络接口相同
interface ens32
#虚拟路由ID号(主备节点一定要相同)
virtual_router_id 103
#本机ip地址
mcast_src_ip 192.168.233.104
#优先级配置(0-254的值)
priority 90
nopreempt
#组播信息发送间隔,两个节点必须配置一致,默认1s
advert_int 1
#认证匹配,此处一定要跟主节点一直
authentication{
auth_type PASS
auth_pass root
}
track_script{
chk_haproxy
}
virtual_ipaddress{
#外部访问的虚拟ip,可以指定多个
192.168.10.110
}
}
#添加脚本,位置/etc/keepalived/haproxy_check.sh(两个节点都要)
COUNT=`ps -C haproxy --no-header | wc -1`
if [$COUNT -eq 0 ];then
/usr/local/haproxy/sbin/haproxy -f /etc/haproxy/haproxy.cfg
sleep 2
if[`ps -C haproxy --no-header | wc -1` -eq 0 ];then
killall keepalived
fi
fi
#脚本授权
chmod +x /etc/keepalived/haproxy_check.sh
PS:当我们启动俩个haproxy节点以后,我们可以启动keepalived服务程序:
//启动两台机器的keepalived
service keepalived start | stop | status | restart
//查看状态
ps -ef | grep haproxy ps -ef | grep keepalived
在keepalived和haproxy都正常运行的情况下,A节点是主节点。
A节点执行ip a命令,会有2个inet的ip,B节点只有一个,然后把A节点的keepalived stop,之后A节点只会有一个,而B节点有2个,这就是高可用故障转移。
此时A节点的keepalived 重新start,会发现vip又回到了A节点。这个可以配置,是否优先使用主节点做vip。
创建如下配置文件位于:/etc/rabbitmq目录下(如果是yum方式安装,会自动创建,如果是绿色安装,这个目录需要自己创建)
环境变量配置文件:rabbitmq-env.conf
配置信息配置文件:rabbitmq.config(可以不创建和配置,修改)
---------------------------------------关键参数配置-------------------------------------------
RABBITMQ_NODE_IP_ADDRESS=本机IP地址
RABBITMQ_NODE_PORT=5672
RABBITMQ_LOG_BASE=/var/lib/rabbitmq/log
RABBITMQ_MNESIA_BASE=/var/lib/rabbitmq/mnesia
配置参考参数如下:
RABBITMQ_NODENAME=FZTEC-240088 节点名称
RABBITMQ_NODE_IP_ADDRESS=127.0.0.1 监听IP
RABBITMQ_NODE_PORT=5672 监听端口
RABBITMQ_LOG_BASE=/data/rabbitmq/log 日志目录
RABBITMQ_PLUGINS_DIR=/data/rabbitmq/plugins 插件目录
RABBITMQ_MNESIA_BASE=/data/rabbitmq/mnesia 后端存储目录
更详细的配置参见: http://www.rabbitmq.com/configure.html#configuration-file
配置文件信息修改:
/usr/lib/rabbitmq/lib/rabbitmq_server-3.6.4/ebin/rabbit.app和rabbitmq.config配置文件配置任意一个即可,我们进行配置如下:
vim /usr/lib/rabbitmq/lib/rabbitmq_server-3.6.4/ebin/rabbit.app
-------------------------------------关键参数配置----------------------------------------
tcp_listerners 设置rabbimq的监听端口,默认为[5672]。
disk_free_limit 磁盘低水位线,若磁盘容量低于指定值则停止接收数据,默认值为{mem_relative, 1.0},即与内存相关联1:1,也可定制为多少byte.
vm_memory_high_watermark,设置内存低水位线,若低于该水位线,则开启流控机制,默认值是0.4,即内存总量的40%。
hipe_compile 将部分rabbimq代码用High Performance Erlang compiler编译,可提升性能,该参数是实验性,若出现erlang vm segfaults,应关掉。
force_fine_statistics, 该参数属于rabbimq_management,若为true则进行精细化的统计,但会影响性能
集群节点模式:Disk为磁盘模式存储/Ram为内存模式存储
更详细的配置参见:http://www.rabbitmq.com/configure.html
集群肯定会出问题,比如某个节点挂了,机房断电,一个节点服务启动不了,磁盘坏了。
遇到这些情况该怎么恢复和故障转移呢?
前提:A和B组成一个镜像队列,B是master
场景1:A先停,B后停
方案1:B是Master,只要先启动B在启动A即可。或者启动A,在30秒之内启动B即可恢复镜像队列
场景2:A、B同时停机
方案2:可能机房掉电等原因造成,只需在30秒之内连续启动A和B即可恢复镜像
场景3:A先停,B后停,且A无法恢复
方案3:该场景是场景1加强版,因为B是Master,所以等B起来后,在B节点上调用控制台命令rabbitmqctl forget_cluster_node A
解除与A的Cluster关系,再将新的Salve节点加入B即可重新恢复镜像队列
场景4:A先停,B后停,且B无法恢复
方案4:该场景是场景3加强版,比较难处理,因为Master节点无法恢复。B是主节点,B无法启动时,A也无法启动,也就无法在A节点上调用rabbitmqctl forget_cluster_node B
。
早在3.1.x时代之前貌似都没什么好的解决方法,但是现在已经有解决方法了,在3.4.2 版本亲测有效。
可以使用新的命令rabbitmqctl forget_cluster_node --offline B
。
这就意味着允许rabbitmqctl在理想节点上执行该命令,迫使RabbitMQ在未启动Slave节点中选择一个节点作为Master。当在A节点执行rabbitmqctl forget_cluster_node --offline B时,RabbitMQ会mock一个节点代表A,执行forget_cluster_node命令将B剔除cluster,然后A就可以正常启动了,最后将新的Slave节点加入A即可重新恢复镜像队列。
场景5:A先停、B后停,且A、B均无法恢复,但是能得到A或B的磁盘文件
方案5:该场景是场景4的加强版,更加难处理。只能通过恢复数据的方式去尝试恢复,将A或B的数据文件默认在$RABBIT_HOME/var/lib目录中,把它拷贝到新节点C的对应目录下,再将新节点C的hostname改成A或B的hostname,如果拷过来的是A节点(Slave)的磁盘文件,则按照场景4处理即可,如果拷过来的是B节点(Master)的磁盘文件,则按照场景3处理,最后将新的Slave加入到新节点完成恢复
场景6:A先停、B后停,且A、B均无法恢复,且得不到A或B的磁盘文件
方案6:无解
``