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集群时应该设置为主动重连模式,目前在测试环境发现部分队列在集群恢复后,不能自动消费数据了。
相关推荐
2401_857610034 分钟前
Spring Boot框架:电商系统的技术优势
java·spring boot·后端
希忘auto21 分钟前
详解MySQL安装
java·mysql
娅娅梨23 分钟前
C++ 错题本--not found for architecture x86_64 问题
开发语言·c++
yaosheng_VALVE24 分钟前
稀硫酸介质中 V 型球阀的材质选择与选型要点-耀圣
运维·spring cloud·自动化·intellij-idea·材质·1024程序员节
汤米粥29 分钟前
小皮PHP连接数据库提示could not find driver
开发语言·php
冰淇淋烤布蕾32 分钟前
EasyExcel使用
java·开发语言·excel
拾荒的小海螺38 分钟前
JAVA:探索 EasyExcel 的技术指南
java·开发语言
Jakarta EE1 小时前
正确使用primefaces的process和update
java·primefaces·jakarta ee
马剑威(威哥爱编程)1 小时前
哇喔!20种单例模式的实现与变异总结
java·开发语言·单例模式
白-胖-子1 小时前
【蓝桥等考C++真题】蓝桥杯等级考试C++组第13级L13真题原题(含答案)-统计数字
开发语言·c++·算法·蓝桥杯·等考·13级