rabbitmq脑裂以及监控添加
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了rabbitmq脑裂以及监控添加相关的知识,希望对你有一定的参考价值。
网络分区的判定RabbitMQ中与网络分区的判定相关的是net_ticktime这个参数,默认为60s。在RabbitMQ集群中的每个broker节点会每隔 net_ticktime/4 (默认15s)计一次tick(如果有任何数据被写入节点中,此节点被认为被ticked),如果在连续四次某节点都没有被ticked到,则判定此节点处于down的状态,其余节点可以将此节点剥离出当前分区。将连续四次的tick时间即为T,那么T的取值范围为 0.75ticktime < T < 1.25ticktime
默认情况下,在45s,日志出现
=ERROR REPORT==== 16-Jul-2017::15:20:55 ===
Mnesia(‘rabbit@node1‘): ** ERROR ** mnesia_event got {inconsistent_database, running_partitioned_network, ‘rabbit@node2‘}
当一个节点起来的时候,RabbitMQ会记录是否发生了网络分区,你可以通过WebUI进行查看;
RabbitMQ GUI上显示
Network partition detected
Mnesia reports that this RabbitMQ cluster has experienced a network partition. There is a risk of losing data. Please read RabbitMQ documentation about network partitions and the possible solutions.
或者可以通过rabbitmqctl cluster_status命令查看,如果查看到信息中的partitions那一项是空的,就像这样
[{nodes,[{disc,[‘rabbit@node1‘, ‘rabbit@node2‘]}]},
{running_nodes,[‘rabbit@node2‘,‘rabbit@node1‘]},
{cluster_name,<<"rabbit@node1">>},
{partitions,[]}]
然而当网络分区时,会变成这样:
[{nodes, [{disc, [‘rabbit@node1‘,‘rabbit@node2‘]}]},
{running_nodes,[‘rabbit@node1‘]},
{cluster_name,<<"rabbit@node1">>},
{partitions, [{‘rabbit@node1‘,[‘rabbit@node2‘]}]}]
当一个RabbitMQ集群发生网络分区时,这个集群会分成两个或者多个分区,它们各自为政,互相都认为对方分区的节点已经down,包括queues,bindings,exchanges这些信息的创建和销毁都处于自身分区内,与其它分区无关。如果原集群中配置了镜像队列,而这个镜像队列又牵涉到两个或者多个网络分区中的节点时,每一个网络分区中都会出现一个master节点,如果分区节点个数充足,也会出现新的slave节点,对于各个网络分区,彼此的队列都是相互独立的,当然也会有一些其他未知的、怪异的事情发生。当网络恢复时,网络分区的状态还是会保持,除非采取一些措施去解决他
自动处理网络分区
RabbitMQ提供了4种处理网络分区的方式,在rabbitmq.config中配置cluster_partition_handling参数即可,分别为:
-
- ignore
-
- pause_minority
-
- pause_if_all_down, [nodes], ignore|autoheal
-
- autoheal
默认是ignore: ignore的配置是当网络分区的时候,RabbitMQ不会自动做任何处理,即需要手动处理
pause_minority: 当发生网络分区时,集群中的节点在观察到某些节点down掉时,会自动检测其自身是否处于少数派(小于或者等于集群中一般的节点数)。少数派中的节点在分区发生时会自动关闭,当分区结束时又会启动。这里的关闭是指RabbitMQ application关闭,而Erlang VM并不关闭,这个类似于执行了rabbitmqctl stop_app命令。处于关闭的节点会每秒检测一次是否可连通到剩余集群中,如果可以则启动自身的应用,相当于执行rabbitmqctl start_app命令。
pause_if_all_down: 在pause_if_all_down模式下,RabbitMQ会自动关闭不能和list中节点通信的节点。语法为{pause_if_all_down, [nodes], ignore|autoheal},其中[nodes]即为前面所说的list。如果一个节点与list中的所有节点都无法通信时,自关闭其自身。如果list中的所有节点都down时,其余节点如果是ok的话,也会根据这个规则去关闭其自身,此时集群中所有的节点会关闭。如果某节点能够与list中的节点恢复通信,那么会启动其自身的RabbitMQ应用,慢慢的集群可以恢复
autoheal: 在autoheal模式下,当认为发生网络分区时,RabbitMQ会自动决定一个获胜的(winning)分区,然后重启不在这个分区中的节点以恢复网络分区。一个获胜的分区是指客户端连接最多的一个分区。如果产生一个平局,既有两个或者多个分区的客户端连接数一样多,那么节点数最多的一个分区就是获胜的分区。如果此时节点数也一样多,将会以一种特殊的方式来挑选获胜分区
oscar cmp目前的配置如下:
rabbitmq.config
[
{rabbit,
[{cluster_nodes,
{[‘rabbit@sh01-oscar-cmp-prod-rmq03‘,‘rabbit@sh01-oscar-cmp-prod-rmq01‘,‘rabbit@sh01-oscar-cmp-prod-rmq02‘],ram }},
{cluster_partition_handling,pause_minority}]},
{kernel,[{net_ticktime, 60}]}
].
可以看出使用的第二种方式
grafana添加报警规则
partitions Current Number of network partitions. 0 is ok. If the cluster is splitted the value is at least 2
由此可以看出,partitions为0时正常,如果集群发生了分裂值至少为2.故我们可以设置partitions值不为0时报警
添加规则:
- alert: Rabbitmq_node_partitions
expr: (rabbitmq_partitions{job="rabbitmq_monitor"}) != 0
for: 2m
labels:
issuetype: "严重"
sourcetype: "中间件"
annotations:
summary: "Instance {{ $labels.instance }} rabbitmq集群节点故障: partitions"
description: "{{ $labels.instance }} of job {{ $labels.job }} on {{ $labels.node }} rabbitmq集群节点故障: partitions"
referenceURL: "http://wiki.virtueit.net/display/CMDT/2.+Maintenance+Manual"
recovered: "recovered"
以上是关于rabbitmq脑裂以及监控添加的主要内容,如果未能解决你的问题,请参考以下文章