参考
Network partition detected
RabbitMQ 之 Clustering 和 Network Partition(翻译)
rabbitmq对network partition的处理
how did we recover from rabbitmq cluster network partition
RabbitMQ入门教程10--partitions
rabbitmq之partitions
0.描述
rabbitmq没有很好的分区容错性,因此,如果需要在广域网里使用rabbitmq集群,建议使用federation或者shovel进行替代。那么即使rabbitmq集群运行在局域网内也不能完全避免网络分区现象(network partition),例如,当路由器或者交换机出现问题,或者网口down掉时,都可能发生网络分区。
当发生网络分区时,不同分区里的节点都认为对方down掉,对exchange,queue,binding的操作都仅针对本分区有效;存储在mnesia的元数据(exchange相关属性,queue相关属性等)不会在集群间进行数据同步;另外,对于镜像队列,在各自的分区里都会存在一个master进程处理队列的相关操作。更重要的是,当网络分区恢复后,这些现象依旧是存在的!
1.现象
#vi /var/log/rabbitmq/rabbit\@mq236.log
=ERROR REPORT==== 30-Mar-2017::00:19:58 ===
Mnesia(rabbit@mq237): ** ERROR ** mnesia_event got {inconsistent_database, running_partitioned_network, rabbit@mq236}
#正常情况
[root@mq236 rabbitmq]# rabbitmqctl cluster_status
Cluster status of node rabbit@mq236 ...
[{nodes,[{disc,[rabbit@mq236,rabbit@mq237,rabbit@mq238]}]},
{running_nodes,[rabbit@mq237,rabbit@mq238,rabbit@mq236]},
{cluster_name,<<"rabbit@mq237">>},
{partitions,[]},
{alarms,[{rabbit@mq237,[]},{rabbit@mq238,[]},{rabbit@mq236,[]}]}]
#network partition异常情况
[root@mq236 rabbitmq]# rabbitmqctl cluster_status
Cluster status of node rabbit@mq236 ...
[{nodes,[{disc,[rabbit@mq236,rabbit@mq237,rabbit@mq238]}]},
{running_nodes,[rabbit@mq237,rabbit@mq236]},
{cluster_name,<<"rabbit@mq237">>},
{partitions,[{rabbit@mq237,[rabbit@mq238]},{rabbit@mq236,[rabbit@mq238]}]},
{alarms,[{rabbit@mq237,[]},{rabbit@mq236,[]}]}]
2.配置项
ignore
默认类型,不处理。
要求你所在的网络环境非常可靠。例如,你的所有 node 都在同一个机架上,通过交换机互联,并且该交换机还是与外界通信的必经之路。pause_minority
rabbitmq节点感知集群中其他节点down掉时,会判断自己在集群中处于多数派还是少数派,也就是判断与自己形成集群的节点个数在整个集群中的比例是否超过一半。如果是多数派,则正常工作,如果是少数派,则会停止rabbit应用并不断检测直到自己成为多数派的一员后再次启动rabbit应用。注意:这种处理方式集群通常由奇数个节点组成。在CAP中,优先保证了CP。
注意:pause_minority适用情形有限制,如3个节点集群,每次只down1个时,此模式适用。但如果网络都出问题,3节点会独立形成3个集群。autoheal
你的网络环境可能是不可靠的。你会更加关心服务的可持续性,而非数据完整性。你可以构建一个包含2个node的集群。
当网络分区恢复后,rabbitmq各分区彼此进行协商,分区中客户端连接数最多的为胜者,其余的全部会进行重启,恢复到同步状态。
3.配置
在/etc/rabbitmq下新建rabbitmq.conf,加入:
[
{rabbit,
[{tcp_listeners,[5672]},
{cluster_partition_handling, pause_minority}
]}
].
4.错误处理
- 选择一个想要保留的集群
- 重启其它分区内所有节点,当它们重新加入集群时,将从信任的分区中恢复状态。其他分区上已发生的操作将丢失。
- 重启信任分区内的所有节点以消除警告。
5.问题
1.设置类型为pause_minority后,一段时间后3节点集群变成3个独立集群;尝试配置为autoheal,一段时间后依然出现变为2个独立集群;
查阅日志(/var/log/rabbitmq/)发现,经常出现heartbeat报错:
=ERROR REPORT==== 30-Mar-2017::17:52:02 ===
closing AMQP connection <0.9426.203> (10.101.232.241:48740 -> 10.102.43.238:5672):
missed heartbeats from client, timeout: 60s
因此尝试将heartbeat从60s设置为200s,观察一段时间后未出现错误。
[
{rabbit,
[{tcp_listeners,[5672]},
{heartbeat,200},
{cluster_partition_handling,autoheal}
]}
].