rabbitmq集群故障恢复详解

rabbitmq集群故障恢复详解

大家好,又见面了,我是全栈君。

RabbitMQ的mirror queue(镜像队列)机制是最简单的队列HA方案,它通过在cluster的基础上增加ha-mode、ha-param等policy选项,可以根据 需求将cluster中的队列镜像到多个节点上,从而实现高可用,消除cluster模式中队列内容单点带来的风险。

在使用镜像队列之前,有几点注意事项必须熟记于心(下文中将混用主节点和master,从节点和slave):

1. 镜像队列不能作为负载均衡使用,因为每个操作在所有节点都要做一遍。

2. ha-mode参数和durable declare对exclusive队列都不生效,因为exclusive队列是连接独占的,当连接断开,队列自动删除。所以实际上这两个参数对exclusive队列没有意义。

3. 将新节点加入已存在的镜像队列时,默认情况下ha-sync-mode=manual,镜像队列中的消息不会主动同步到新节点,除非显式调用同步命令。当 调用同步命令(via rabbitmqctl or web-based ui)后,队列开始阻塞,无法对其进行操作,直到同步完毕。当ha-sync-mode=automatic时,新加入节点时会默认同步已知的镜像队列。 由于同步过程的限制,所以不建议在生产环境的active队列(有生产消费消息)中操作。

4. 每当一个节点加入或者重新加入(例如从网络分区中恢复回来)镜像队列,之前保存的队列内容会被清空。

5. 镜像队列有主从之分,一个主节点(master),0个或多个从节点(slave)。当master宕掉后,会在slave中选举新的master。选举算法为最早启动的节点。

6. 当所有slave都处在(与master)未同步状态时,并且ha-promote-on-shutdown policy设置为when-syned(默认)时,如果master因为主动的原因停掉,比如是通过rabbitmqctl stop命令停止或者优雅关闭OS,那么slave不会接管master,也就是说此时镜像队列不可用;但是如果master因为被动原因停掉,比如VM 或者OS crash了,那么slave会接管master。这个配置项隐含的价值取向是优先保证消息可靠不丢失,放弃可用性。如果ha-promote-on- shutdown policy设置为alway,那么不论master因为何种原因停止,slave都会接管master,优先保证可用性。

7. 镜像队列中最后一个停止的节点会是master,启动顺序必须是master先起,如果slave先起,它会有30秒的等待时间,等待master启动, 然后加入cluster。当所有节点因故(断电等)同时离线时,每个节点都认为自己不是最后一个停止的节点。要恢复镜像队列,可以尝试在30秒之内同时启 动所有节点。

8. 对于镜像队列,客户端basic.publish操作会同步到所有节点;而其他操作则是通过master中转,再由master将操作作用于salve。 比如一个basic.get操作,假如客户端与slave建立了TCP连接,首先是slave将basic.get请求发送至master,由 master备好数据,返回至slave,投递给消费者。

9. 由8可知,当slave宕掉时,除了与slave相连的客户端连接全部断开之外,没有其他影响。当master宕掉时,会有以下连锁反应:1)与 master相连的客户端连接全部断开。2)选举最老的slave为master。若此时所有slave处于未同步状态,则未同步部分消息丢失。3)新的 master节点requeue所有unack消息,因为这个新节点无法区分这些unack消息是否已经到达客户端,亦或是ack消息丢失在到老 master的通路上,亦或是丢在老master组播ack消息到所有slave的通路上。所以处于消息可靠性的考虑,requeue所有unack的消 息。此时客户端可能受到重复消息。4)如果客户端连着slave,并且basic.consume消息时指定了x-cancel-on-ha- failover参数,那么客户端会收到一个Consumer Cancellation Notification通知,Java SDK中会回调Consumer接口的handleCancel()方法,故需覆盖此方法。如果不指定x-cancel-on-ha-failover参 数,那么消费者就无法感知master宕机,会一直等待下去。

上面列出的注意事项整理自官方的HA文档

下面的镜像队列恢复才是本文重点:

* 前提:两个节点(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的加强版,比较难处理,早在3.1.x时代之前貌似都没什么好的解决方法,可能是我不知道,但是现在已经有解决方法了,在3.4.2 版本亲测有效。因为B是master,所以直接启动A是不行的,当A无法启动时,也就没办法在A节点上调用rabbitmqctl forget_cluster_node B了。新版本中,forget_cluster_node支 持–offline参数,offline参数允许rabbitmqctl在离线节点上执行forget_cluster_node命令,迫使 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的磁盘文件。

该场景是场景4的加强版,更加难处理。将A或B的数据库文件(默认在$RABBIT_HOME/var/lib目录中)拷贝至新节点C的目录下,再 将C的hostname改成A或B的hostname。如果拷过来的是A节点磁盘文件,按场景4处理方式;如果拷过来的是B节点磁盘文件,按场景3处理方 式。最后将新的slave节点加入C即可重新恢复镜像队列。

* 场景6:A先停,B后停,且A、B均无法恢复,且无法得到A或B的磁盘文件。

洗洗睡吧,该场景下已无法恢复A、B队列中的内容了。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/108648.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 加拿大pc28算法公式(车辆调度算法)

    百度Apollo2.0车辆控制算法之LQR控制算法解读Apollo中横向控制的LQR控制算法在Latcontroller..cc中实现根据车辆的二自由度动力学模型(1)根据魔术公式在小角度偏角的情况下有,轮胎的侧向力与轮胎的偏离角成正比.,分别为前、后轮的侧偏刚度,(2)(3)在小角度的情况下有所以有(4)因此上述车辆的动力学模型可以简化写成(5)…

    2022年4月18日
    37
  • Git创建远程分支并提交代码到远程分支[通俗易懂]

    Git创建远程分支并提交代码到远程分支[通俗易懂]1、可以通过gitbranch-r命令查看远端库的分支情况如图所示,远程仓库只有一个master分支2、从已有的分支创建新的分支(如从master分支),创建一个dev分支但此时并没有在远程仓库上创建分支如图所示还是只有一个master分支3、建立本地到远端仓库的链接–这样代码才能提交上去使用命令行gitpush–set-…

    2022年6月30日
    46
  • CSS选择器及优先级 总结

    CSS选择器及优先级 总结一、优先级不同级别在属性后面使用!important会覆盖页面内任何位置定义的元素样式。作为style属性写在元素内的样式id选择器类选择器元素选择器通配符选择器浏览器自定义或继承总结排序:!important>行内样式>ID选择器>类选择器>元素>通配符>继承&a

    2022年7月27日
    6
  • 免备案cdn_cdn贝安装

    免备案cdn_cdn贝安装免备案CDN,符码CDN应该是使用CDN贝搭建,该CDN系统相对来说比较成熟,功能支持比较丰富。今天对符码免备案CDN进行简单的测试,仅供大家参考。首先,就是简单粗暴的多地区PING大法,简单看下CDN延迟效果:如果要是对比那么多免备案CDN延迟来说,符码CDN平均可以做到45ms的延迟,无疑是测试的所有免备案CDN中多地区PING平均延迟最小的一个,甚至一些国内CDN也达不到这个低延迟效果,延迟…

    2025年8月30日
    7
  • c语言中按位异或运算,^按位异或运算符「建议收藏」

    c语言中按位异或运算,^按位异或运算符「建议收藏」^表示按位异或运算符,顾名思义,相异,即不同则为1,反之为0例如15和16进行异或运算,运算过程如下:15000000000000000000000000000011111600000000000000000000000000010000^——————————————000000000000…

    2022年5月3日
    38
  • 【Java 8 新特性】Java LocalDate 转 Date

    【Java 8 新特性】Java LocalDate 转 DateJavaLocalDate转Date1.使用LocalDate.atTime2.使用LocalDate.atStartOfDay3.使用LocalDateTime.of4.使用Timestamp.valueOf完整示例参考文献在这一页,我们将提供如何将java.time.LocalDate转换成java.util.Date。LocalDate表示一个格式为yyyy-MM-dd的日期,如2019-05-08。我们可以使用以下方法和构造函数来创建一个Date对象。1.Date.f

    2022年10月4日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号