今天来说说 RabbitMQ 镜像队列集群的几种故障场景 以及对应的恢复方案。
前提: 节点 A 和节点 B 组成一个镜像队列
场景1:A 先停了,B 后停
解决方案:该场景下 B 是 master,主要先启动 B,再启动 A 即可。或者 先启动 A,在 30 秒内启动 B 即可恢复镜像队列
场景2:A、B 同时停机
解决方案:该场景可能是由于机房掉电等原因造成的,只需要在 30 秒之内连续启动 A 和 B 即可恢复镜像队列
场景 3 : A先停,B 后停,且 A 无法恢复
方案: 该场景是 场景 1 的加强版,因为 B 是 master, 所以等 B 起来以后,在 B 节点上调用控制台命令: rabbitmqctl forget_cluster_node A 解除与 A 的 cluster 关系,再将新的 slave 节点加入 B 即可重新恢复镜像队列
场景 4: A 先停,B 后停,且 B 无法恢复
方案:该场景是场景 3 的升级版,比较难处理,原因是 因为 master 节点无法恢复。在 3.1.X 时代之前没有什么好的解决方案,但是在 3.4.2 以后的版本可以试试 - -offline 这个参数。
注意是 : - - 两个 - 的
因为 B 是 主节点,所以直接启动 A 是不行的,当 A 无法启动的时候,也就没有办法在 A 节点上调用之前的 rabbitmq forget_cluster_node B 命令了。新版本中, forget_cluster_node 支持 -offline 参数。这就意味着允许 rabbitmqctl 在理想节点上执行该命令,迫使 rabbitMQ 会 mock 一个 一个节点代表 A,执行 forget_cluster_node 命令将 B 剔除 cluster,然后 A 就可以正常启动了,最后将新的 slave 节点加入 A 即可重新恢复镜像队列
场景 5 : A 先停,B 后停,且 A、B 均无法恢复,但是能得到 A 或 B 的磁盘文件
解决方案:只能通过恢复数据的方式进行尝试恢复,将 A 或 B 的数据库文件 默认在 $RABBIT_HOME/var/lib/ 目录下,把它 拷贝到新节点的对应目录下,再将新节点的 hostname 改成 A 或者 B 的 hostname。如果是 A 节点(slave)的磁盘文件,则按照场景 4 处理即可;如果是 B 节点(master)的磁盘文件,则按照场景 3 处理,最后将新的 slave 加入到新节点后完成恢复。
场景 6: A 先停、B 后停,且 A 、B 均无法恢复,且得不到 A 或 B 的磁盘文件
解决方案:可以洗洗睡了~没有方案,解决不了!
网友评论