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 为空

网络分区手动解决完成。

 

posted @ 2021-07-19 14:45  运维小兵#杨  阅读(777)  评论(0)    收藏  举报