RabbitMQ3.7.8集群分区(脑裂现象)模拟及恢复处置全场景测试

测试环境准备: MQ服务器集群地址,版本号为3.7.8:

管理控制台地址:http://173.101.4.6:15672/#/queues

集群状态 rabbitmqctl cluster_status

集群操作相关命令:

创建一个RabbitMQ集群涉及到如下步骤:

安装RabbitMQ : 在每台要在集群中运行的机器上安装RabbitMQ。可以参考RabbitMQ官方文档

配置.erlang.cookie文件: RabbitMQ基于Erlang语言。其中.erlang.cookie文件用于在Erlang节点之间进行通信。在一个集群里,所有服务器的.erlang.cookie文件必须保持一致。这个文件通常位于用户的主目录下(/var/lib/rabbitmq)。拷贝一台机器上的.erlang.cookie文件内容到其它所有服务器上。

开始配置集群: 在一台机器上启动RabbitMQ应用,然后在所有其他机器上执行下面命令,加入到集群中(例如,你想把mq2,mq3加入到mq1的集群中):

rabbitmqctl stop_app

rabbitmqctl reset

rabbitmqctl join_cluster rabbit@mq1

rabbitmqctl start_app

验证集群配置: 使用下面的命令在每台机器上检查集群状态,保证它们都在集群中:

rabbitmqctl cluster_status

添加节点到集群: 首先,停止你想要添加到集群的节点的应用进程。你可以使用 rabbitmqctl stop_app 命令。然后,使用 rabbitmqctl join_cluster <clusternode> 命令将节点加入到集群。这里,<clusternode>应该被替换为集群中的一个运行的节点。最后,再使用 rabbitmqctl start_app 命令启动应用。

从集群中移除节点: 你需要先停止你想要移除的节点的应用进程。然后,执行 rabbitmqctl forget_cluster_node <node> 命令。这里,<node>应该被替换为你要从集群中移除的节点。即使节点已经停止运行或者从网络上移除,你仍然需要在集群中的一个运行的节点上执行此命令,来从集群元数据中删除该节点。

举例:

  1. 添加节点到集群:

在新节点上执行以下命令,将其加入集群:

rabbitmqctl stop_app

rabbitmqctl reset # Be careful, this will remove all data on the node

rabbitmqctl join_cluster rabbit@mq01.omms.com

rabbitmqctl start_app

上面的命令中, rabbit@mq01.omms.com 应被替换为你的集群中任意一个运行的节点。

注意: rabbitmqctl reset 命令会清除当前节点上所有的数据和配置,执行该命令前,请确保该节点上没有需要保留的数据。

  1. 从集群中删除节点:
    在集群中任意一个运行的节点上执行以下命令,将节点从集群中删除:

rabbitmqctl forget_cluster_node rabbit@mq02.omms.com

上面的命令中, rabbit@mq02.omms.com 应被替换为你要移除的节点。

注意: 即使你移除的节点已经停止运行或者与网络断开连接,你仍需要运行 rabbitmqctl forget_cluster_node 命令来清除集群中的元数据。

模拟集群分区(脑裂现象),命令准备

阻止mq01与其他节点通讯:

iptables -A INPUT -s 173.101.4.7 -j DROP

iptables -A INPUT -s 173.101.4.8 -j DROP

iptables -A OUTPUT -d 173.101.4.7 -j DROP

iptables -A OUTPUT -d 173.101.4.8 -j DROP

以上命令将mq01与mq02和mq03之间的通信丢弃。此时,mq01与其他节点无法通信,从而模拟了网络分区的情况。

恢复mq01与其他节点通讯:

iptables -D INPUT -s 173.101.4.7 -j DROP

iptables -D INPUT -s 173.101.4.8 -j DROP

iptables -D OUTPUT -d 173.101.4.7 -j DROP

iptables -D OUTPUT -d 173.101.4.8 -j DROP

以上命令解除了mq01与其他节点的通信阻止。这样,mq01就可以恢复与mq02和mq03的正常通信了。但是因为数据不同步,导致脑裂现象。

查看集群集群分区后状态

集群分区处置流程:

RabbitMQ集群分区处置模式设置:

cluster_partition_handling 这个选项有三个可能的值:ignore, autoheal, pause_minority。

ignore: 这是默认设置,意味着RabbitMQ在网络分区发生时将无视网络分区,每个分区将独立运作,分区解决后将要耗费很长时间来同步数据。

autoheal: 这个设置会在发生网络分区时,强制节点从最大的分区(copying its state)中自我恢复,这个过程称为"healing",healing过程结束后可即刻恢复服务。(最常用的设置,通过RabbitMQ自行恢复)

pause_minority:这个设置会在网络分区发生时,检测哪个分区的节点最多,然后暂停节点较少的分区。这可能会导致RabbitMQ服务暂停,但是当分区修复后,服务可以立即恢复。

在新版本的RabbitMQ(3.7.0以上)中,推荐使用新的配置文件格式,即rabbitmq.conf。你可以按如下方式来修改cluster_partition_handling的设置:

173.101.4.6、173.101.4.7、173.101.4.8三台均配置

打开你的rabbitmq.conf文件,你可以使用以下命令:

 sudo vi /etc/rabbitmq/rabbitmq.conf

在文件的末尾,添加以下内容:

cluster_partition_handling = autoheal

保存并关闭文件。

如果mq状态为暂停,则重启RabbitMQ服务,如果状态正常则无需重启:

 sudo service rabbitmq-server restart

然后再依次重启,173.101.4.7和173.101.4.8。

测试结论:

  1. 3.7.8版本的RabbitMQ,仍然存在网络波动的状态下出现集群分区的风险。
  2. 经过测试环境验证。建议在MQ集群配置的时候,增加集群分区处置模式的配置,即在++++/etc/rabbitmq/rabbitmq.conf++++ 增加++++cluster_partition_handling = autoheal++++ ,如果有这个配置,网络状态恢复后,MQ分区模式会自动恢复,无需手动去恢复。如果无该配置,需要手动进行恢复。
  3. 应用程序端在连接MQ集群时应该设置为主动重连模式,目前在测试环境发现部分队列在集群恢复后,不能自动消费数据了。
相关推荐
ZJ_.1 分钟前
WPSJS:让 WPS 办公与 JavaScript 完美联动
开发语言·前端·javascript·vscode·ecmascript·wps
Narutolxy6 分钟前
深入探讨 Go 中的高级表单验证与翻译:Gin 与 Validator 的实践之道20241223
开发语言·golang·gin
Hello.Reader14 分钟前
全面解析 Golang Gin 框架
开发语言·golang·gin
禁默24 分钟前
深入浅出:AWT的基本组件及其应用
java·开发语言·界面编程
Cachel wood31 分钟前
python round四舍五入和decimal库精确四舍五入
java·linux·前端·数据库·vue.js·python·前端框架
Code哈哈笑34 分钟前
【Java 学习】深度剖析Java多态:从向上转型到向下转型,解锁动态绑定的奥秘,让代码更优雅灵活
java·开发语言·学习
gb421528737 分钟前
springboot中Jackson库和jsonpath库的区别和联系。
java·spring boot·后端
程序猿进阶37 分钟前
深入解析 Spring WebFlux:原理与应用
java·开发语言·后端·spring·面试·架构·springboot
qq_4336184439 分钟前
shell 编程(二)
开发语言·bash·shell