1、脑裂问题产生的原因
rabbitmq中02-03的链接和01断开,通过rabbitmq管理界面发现,每个rabbitmq都正常,各自分裂了3个分区,通过官方文档查询发现
如果另一个节点在一段时间内(默认为 60 秒)无法与其联系,则节点会确定其对等方是否关闭。如果两个节点重新接触,并且都认为另一个节点已关闭,则节点将确定发生了分区。这将以如下形式写入 RabbitMQ 日志:
2020-05-18 06:55:37.324 [error] <0.341.0> Mnesia(rabbit@warp10): ** ERROR ** mnesia_event 得到 {inconsistent_database, running_partitioned_network, rabbit@hostname2}
官方文档地址: https://www.rabbitmq.com/partitions.html
官方文档中明确指出,在120s内会发出4个心跳,在 150s内没有返回应答,则会判断节点下线(120*125%)
参数可以由advanced.config 中配置一下参数加长心跳检测的时间
[
{kernel, [{net_ticktime, 120}]}
].
OK原因已经分析完毕,由于网络造成rabbitMQ的集群间通讯出现了问题。
2、解决方案
1、脑裂产生后,即使rabbitMQ之间通讯恢复默认情况下,也不会自动的进行集群间的数据同步,需要人工介入重启集群,启动顺序建议数据最全的最后启动 2、重启会出现 rabbitMQ 左上角提示数据未同步的状态,这里没有截图了 需要进入未同步的队列手工点击同步,已进行镜像队列的同步 3、同步完毕后rabbitMQ镜像集群恢复正常
3、后续处理
3.1 配置自动同步镜像对列
为何镜像队列会出现需要手动同步的情况呢?
RabbitMQ中队列有两种模式
1.默认 Default
2.镜像 Mirror
*镜像队列master和salver之间通过日志回放的机制进行同步
如果其中某一个节点挂掉了,再重启的时候,node的数据是不会再同步的。 参数ha-sync-mode
镜像队列有一个配置参数ha-sync-mode,这个参数有2中取值:automatic, manual。
manual是默认值。如果镜像队列被设置成munual,当一个slave加入和重新加入队列时的行为,就是我们上面描述的行为,之所以叫manual,就是我们可以通过命令行手工(manually)进行同步。命令如下: rabbitmqctl sync_queue name
如果镜像队列被设置成automatic,当一个新slave加入时,slave会自动同步master中的所有消息,直到所有消息被同步完成之前,所有的操作都会被阻塞(blocking)。
这个参数是可用性和可靠性的一个平衡,manual不保证数据可靠性,在某些情况会出现丢消息的可能,但是保证了队列的可用性。automatic提高了数据的可靠性,但是当有新slave加入时,可能会出现队列的暂时不可用。
具体配置步骤
3.2配置rabbitMQ脑裂后的恢复策略
由官方文档可知 恢复策略分为3种
1、autoheal 不做任何车里 2、pause_minority 少数派分区自动重启 3、pause_if_all_down 可以指定一个白名单,当一个节点和白名单中的节点都无法通讯的时候,自身就关闭,等待通信恢复后启动
依据这几种策略,考虑到现网部署了3台,采用pause_minority为最佳策略。并且不容易丢数据 在rabbitMQ的配置文件 rabbitmq.conf中增以下配置
[
{
rabbit, [
{cluster_partition_handling, pause_minority}
]
}
].
3.3增加监控
rabbitMQ监听端口如下
RabbitMQ节点绑定到端口(打开服务器TCP套接字)以接受客户端和CLI工具连接。其他进程和工具(如SELinux)可能会阻止RabbitMQ绑定到端口。发生这种情况时,节点将无法启动。CLI工具,客户端库和RabbitMQ节点也打开连接(客户端TCP套接字)。防火墙可以防止节点和CLI工具相互通信。确保可以访问以下端口:
4369:epmd,RabbitMQ节点和CLI工具使用的对等发现服务 5672,5671:AMQP 0-9-1和1.0客户端使用没有和使用TLS 25672:用于节点间和CLI工具通信(Erlang分发服务器端口),并从动态范围分配(默认情况下限于单个端口,计算为AMQP端口+ 20000)。除非确实需要这些端口上的外部连接(例如,群集使用联合或CLI工具在子网外的计算机上使用),否则不应公开这些端口。有关详情, 请参阅网络指南 35672-35682:由CLI工具(Erlang分发客户端端口)用于与节点通信,并从动态范围(计算为服务器分发端口+ 10000到服务器分发端口+ 10010)进行分配。有关详情, 请参阅网络指南 15672:HTTP API客户端,管理UI和rabbitmqadmin(仅当启用了管理插件时) 61613,61614:没有和使用TLS的STOMP客户端(仅当启用了STOMP插件时) 1883,8883 如果启用了MQTT插件,则没有和使用TLS的MQTT客户端 15674:STOMP-over-WebSockets客户端(仅当启用了Web STOMP插件时) 15675:MQTT-over-WebSockets客户端(仅当启用了Web MQTT插件时)
由rabbitMQ侦听端口可知,25672为节点间的通讯端口,可配置对此端口的监控来感知节点间通讯故障。
后续其他监控参考官方文档 https://www.rabbitmq.com/memory-use.html
|