RabbitMQ 集群的网络分区容错性并不是非常高,在网络经常发生分区时会有些问题,最明显的就是脑裂问题。
官方文档是这样介绍的:
RabbitMQ clusters do not tolerate network partitions well. If you are thinking of clustering across a WAN, don't. You should use federation or the shovel instead.
从中我们可以看出,在广域网环境下不应该使用集群,而应该使用 federation 或者 shovel 来解决。
不过即使是在局域网环境下,网络分区也不可能完全避免,网络设备(比如中继设备、网卡)出现故障也会导致网络分区。
Network partition detected
Mnesia reports that this RabbitMQ cluster has experienced a network partition. This is a dangerous situation. RabbitMQ clusters should not be installed on networks which can experience partitions.
当出现网络分区时,不同分区里的节点会认为不属于自身所在分区的节点都已经挂了,对 queue、exchange、binding 的操作仅对当前分区有效。在 RabbitMQ 的默认配置下,即使网络恢复了也不会自动处理网络分区带来的问题从而恢复集群。RabbitMQ(3.1+)会自动探测网络分区,并且提供了配置来解决这个问题。
[ {rabbit, [{tcp_listeners,[5672]}, {cluster_partition_handling, ignore}] } ].
RabbitMQ 提供了三种配置:
- ignore:默认配置,发生网络分区时不作处理,当认为网络是可靠时选用该配置
- autoheal:各分区协商后重启客户端连接最少的分区节点,恢复集群(CAP 中保证 AP,有状态丢失)
- pause_minority:分区发生后判断自己所在分区内节点是否超过集群总节点数一半,如果没有超过则暂停这些节点(保证 CP,总节点数为奇数个)
参考: