rabbitmq网络分区问题
一、网络分区的判定
网络分区的发生多与网络问题有关,RabbitMQ中net_ticktime这个参数用来判定网络分区,默认为60s。在集群中的每个节点会每隔 net_ticktime的1/4 (也就是默认15秒)来计一次tick,如果有任何数据被写入此节点中,那么此节点被ticked,一个节点连续四次都没有被ticked,也就是net_ticktime设置的时间内没有数据写入,那么这么节点就被判定为down,其余的节点将此节点踢出当前分区。
二、自动处理
发生网络分区后,要么自动处理,要么手动处理,自动处理通常会有4种自动处理的方式:
1. ignore
如果不配置rabbitmq.config,默认是ignore,意思是当网络分区的时候,不做自动处理,即需要手动处理。
[
{ rabbit, [ {cluster_partition_handling, ignore}
]
}
].
2.pause_minority
在rabbitmq.config配置文件中配置:
[
{ rabbit, [ {cluster_partition_handling, pause_minority}
]
}
].
集群中的节点检测到某些节点down了,会判断自己是否属于小于等于集群一半节点数,如果属于少数则会关闭app,此时erlang虚拟机是运行的,然后每秒会检测一次其它分区的连通性,如果连通正常,则启动app,集群恢复正常。因为这个原因,所以集群节点为2或者偶数时,不适合用此配置,可能会造成俩个分区全部关闭的情况。最好是奇数集群。
3.autoheal
在rabbitmq.config配置文件中配置:
[
{ rabbit, [ {cluster_partition_handling, autoheal}
]
}
].
在autoheal模式下,当认为发生网络分区时,RabbitMQ会自动决定一个获胜的(winning)分区,然后重启不在这个分区中的节点以恢复网络分区。一个获胜的分区是指客户端连接最多的一个分区。如果产生一个平局,既有两个或者多个分区的客户端连接数一样多,那么节点数最多的一个分区就是获胜的分区。如果此时节点数也一样多,将会以一种特殊的方式来挑选获胜分区。
4.pause_if_all_down
有两种配置:
[ { rabbit, [ {cluster_partition_handling, {pause_if_all_down, ['rabbit@node1'], ignore}} ] } ].
------------------------------------------------------------------------------------------------------------
[
{
rabbit, [
{cluster_partition_handling, {pause_if_all_down, ['rabbit@node1'], autoheal}}
]
}
].
语法是
{pause_if_all_down, [nodes], ignore|autoheal}
[nodes] 是用来检测节点通信的节点列表,如果此节点和list中的节点都不能通信,则判断此节点down。如果list中的节点都down,那么这个集群的所有节点都会down,这时候只有恢复list中的节点正常,才能恢复整个集群。
ignore|autoheal 有一种特殊情况,当list中的节点不能互相通信,发生网络分区后在各自分区内的节点都能与list中某个节点通信,这种情况下即使发生了网络分区,那么节点都不会关闭。所以这个参数决定了分区后无法关闭节点的后续操作
三、手动处理
在节点上执行命令
[root@rabbitmq01 rabbitmq-3.6.6]# rabbitmqctl cluster_status Cluster status of node rabbit@rabbitmq01 ... [{nodes,[{disc,[rabbit@rabbitmq03]}, {ram,[rabbit@rabbitmq02,rabbit@rabbitmq01]}]}, {running_nodes,[rabbit@rabbitmq03,rabbit@rabbitmq01]}, {cluster_name,<<"rabbit@rabbitmq03">>}, {partitions,[{rabbit@rabbitmq03,[rabbit@rabbitmq02]}, {rabbit@rabbitmq01,[rabbit@rabbitmq02]}]}, {alarms,[{rabbit@rabbitmq03,[]},{rabbit@rabbitmq01,[]}]}] # partitions 这行如果不为空 则说明出现网络分区
选择一个节点做为信任节点,重启其他节点,其他节点的数据会丢失
# 重启节点2 [root@rabbitmq02 rabbitmq-3.6.6]# rabbitmqctl stop_app Stopping node rabbit@rabbitmq02 ... [root@rabbitmq02 rabbitmq-3.6.6]# rabbitmqctl start_app Starting node rabbit@rabbitmq02 ... # 重启节点3 [root@rabbitmq03 rabbitmq-3.6.6]# rabbitmqctl stop_app Stopping node rabbit@rabbitmq03 ... [root@rabbitmq03 rabbitmq-3.6.6]# rabbitmqctl start_app Starting node rabbit@rabbitmq03 ...
此时回到节点1
[root@rabbitmq01 rabbitmq-3.6.6]# rabbitmqctl cluster_status Cluster status of node rabbit@rabbitmq01 ... [{nodes,[{disc,[rabbit@rabbitmq03]}, {ram,[rabbit@rabbitmq02,rabbit@rabbitmq01]}]}, {running_nodes,[rabbit@rabbitmq03,rabbit@rabbitmq02,rabbit@rabbitmq01]}, {cluster_name,<<"rabbit@rabbitmq03">>}, {partitions,[]}, {alarms,[{rabbit@rabbitmq03,[]}, {rabbit@rabbitmq02,[]}, {rabbit@rabbitmq01,[]}]}] partitions 为空
网络分区手动解决完成。
浙公网安备 33010602011771号