rabbitmq实战指南_RabbitMQ之脑裂

本文详细介绍了RabbitMQ集群中网络分区的判定机制,与net_ticktime参数的关系,以及当出现网络分区时的处理策略。当节点间的通信端口25672出现问题,导致网络中断,RabbitMQ会通过net_ticktime超时判断网络分区,并在连续4次未收到节点响应时将其标记为“down”。网络分区发生时,可以选择挂起生产者或消费者进程以减少消息丢失,或进行人工介入处理。
摘要由CSDN通过智能技术生成
点击上方 蓝色字体 ,选择“设为星标”

e704f416d87c86aaf7705037d03318c8.png

9

10

本文总结《RabbitMQ实战指南》网络分区章节,并亲自实践才有这篇文章,手动处理章节详细记录了操作过程中的注意事项.如果你没有经历过网络分区,就不算真正掌握RabbitMQ~

1

网络分区(脑裂)

网络分区对于RabbitMQ本身而言有利有弊,在遇到网络分区时不必过于惊慌. 许多情况下,网络分区都是由单个节点的网络故障引起的,而且通常会形成一个大分区和一个单节点的分区,如果之前又配置了镜像,那么可以在不影响服务可用性、不丢失消息的情况下从网络分区的情形下恢复.

当一个集群发生分区时,这个集群会分成两个部分或者更多,他们各自为政.互相都认为对方分区内的节点已经挂了,包括队列、交换器及绑定等元数据的穿件和销毁都处于自身分区内,与其他分区无关.如果原集群中配置了镜像队列,而这个镜像队列又牵涉两个或者更多个网络分区中的节点时,每一个网络分区中都会出现一个master节点,对于各个网络分区,次队列都是相互独立.当然也会又一些其他未知的、怪异的事情发生.当网络恢复时,网络分区的状态还是会保持,除非你采取了一些措施去解决它.

2

网络分区的判定

RabbitMQ集群节点内部通信端口默认为:25672,两两节点之间都会有信息交互.如果某节点出现网络故障,或者端口不通,则会致使与此节点的交互出现中断,这里就会有个超时判断机制,继而判定网络分区,下面段落详细介绍了分区的判断.

对于网络分区的判定是与net_ticktime这个参数息息相关的,此参数默认值为:60秒.注意与heartbeat_time的区别,heart_time是指客户端与RabbitMQ服务之间通信的心跳时间,针对5672端口而言.如果发生超时则会有net_tick_timeout的信息报出.在RabbitMQ集群内部的每个节点之间会每隔四分之一的net_ticktime记一次应答(tick).如果有任何数据被写入节点中,则此节点被认为已经被应答(ticked)了,如果连续4次,某个节点没有被应答(ticked),则可以判定次节点已经处于:“down”状态,其余节点可以将次节点剥离出当前分区.

将连续4次的tick时间记为T,那么T的取值范围为:

    0.75 * net_ticktime < T < 1.25 * net_ticktime

如图可以形象地描绘出这个取值范围的缘由:

d479979e8b9497b9133fd2700290b7f8.png 如图中每个节点代表一次tick判定的时间戳,在2个临界值0.75 * net_ticktime 和1.25 * net_ticktime之间可以连续执行4次的tick判定.默认情况下,在45s < T <75s之间会判定出net_tick_timeout. RabbitMQ不仅会将队列、交换器及绑定等信息存储在Mnesia数据库中,而且许多围绕网络分区的一些细节也都和这个Mnesia的行为相关. 如果一个节点不能在T时间连上另一个节点,那么Mesia通常认为这个节点已经挂了,就算之后两个节点又恢复了内部通信,但是这两个节点都会认为对方已经挂了,Mnesia此时认定了网络分区的情况. 这些会被记录到RabbitMQ的服务日志之中,如下:
=ERROR REPORT==== 9-Aug-2020::20:15:45 ===
Mnesia('rabbit@rmq-node2'): ** ERROR ** mnesia_event got {inconsistent_database, starting_partitioned_network, 'rabbit@rmq-node1'}
除了通过查看RabbitMQ服务日志的方式,还有以下3种方法可以查看是否出现了网络分区

3

网络分区查看 1、通过rabbitmqctl工具查看 即采用rabbitmqctl cluster_status命令.未发生分区的情况,如下图:
[root@rmq-node3 ~]# rabbitmqctl cluster_status
Cluster status of node 'rabbit@rmq-node3'
[{nodes,[{disc,['rabbit@rmq-node2','rabbit@rmq-node1']},
         {ram,['rabbit@rmq-node3']}]},
 {running_nodes,['rabbit@rmq-node1','rabbit@rmq-node2','rabbit@rmq-node3']},
 {cluster_name,<<"rabbit@rmq-node1">>},
 {partitions,[]}, #注意,这里为空数组,表明没有发生网络分区
 {alarms,[{'rabbit@rmq-node1',[]},
          {'rabbit@rmq-node2',[]},
          {'rabbit@rmq-node3',[]}]}]

发生分区的情况:

[root@rmq-node3 ~]# rabbitmqctl cluster_status
Cluster status of node 'rabbit@rmq-node3'
[{nodes,[{disc,['rabbit@rmq-node2','rabbit@rmq-node1']},
         {ram,['rabbit@rmq-node3']}]},
 {running_nodes,['rabbit@rmq-node1','rabbit@rmq-node2','rabbit@rmq-node3']},
 {cluster_name,<<"rabbit@rmq-node1">>},
 {partitions,[{'rabbit@rmq-node1',['rabbit@rmq-node2','rabbit@rmq-node3']}]}, #这里是发生了network partitions
 {alarms,[{'rabbit@rmq-node1',[]},
          {'rabbit@rmq-node2',[]},
          {'rabbit@rmq-node3',[]}]}]
2、通过RabbitMQ管理控制台查看 4e456464abf04018e14e460537ef46f3.png 3、通过HTTP API 接口调用节点信息查看 400a6cab589030573c712510ebb97a88.png 见到红色方框信息则表示发生了分区 76ce03c8c5ae67f0f6f9d950c3d82571.png

4

网络分区之手动处理 a、步骤1

挂起生产者或者消费者进程. 这样可以减少消息不必要的丢失,如果进程数过多,情形又比较紧急,也可以跳过次步骤.

b、步骤2 删除镜像队列的配置. 使用命令:rabbitmqctl clear_policy [-p vhost] {policy_name} , 命令删除示例 ( 也可以在web管理台删除):
rabbitmqctl clear_policy -p /xmm ha-all
为什么要做这一步? : 因为不做这一步会队列发生漂移,所有的master会漂移到同一个节点上.还要注意:
1. 每个分区都要删除,如果只删除一个分区,是不行的2. 查看policy的命令为:rabbitmqctl list_policies [-p ]       eg:rabbitmqctl list_policies -p /xmm
c、步骤3挑选信任分区. 挑选的优先级如下:

f76a6d61043d5d59189f29cc47a50959.png

d、步骤4关闭所有非信任区节点. 采用rabbitmqctl stop_app命令关闭注意:关闭所有的非信任分区的节点,就是全部关闭; 绝对不能关闭一个重启一个,这样不但解决不来问题,还会出现新的分区e、步骤5启动非信任分区中的节点.采用rabbitmqctl start_app命令启动f、步骤6检查网络分区是否恢复,如果已经恢复则转步骤8;如果还有网络分区的报警则转步骤7注意:检查方法,可以参考:3、网络分区查看g、步骤7重启信任分区中的节点.可以挨个重启h、步骤8重新添加镜像队列的配置,可以使用如下命令(也可以使用管理控制台):
rabbitmqctl set_policy [-p vhost] [--priority priority] [--apply-to apply-to] {name} {pattern} {definition}
# {name} 表示策略名称;# {pattern} 表示当匹配到给定资源的正则表达式,使该策略得以应用; # {definition} 表示策略的定义,作为一个JSON项,在多数shell中,你很可能需要去应用它# {priority} 表示策略的优先级的整数,数据越大表示优先级越高,默认值为0# {apply_to} 表示策略应该应用的类型:queues/exchange/all,默认值是 all也可以指定模式,举例如下:
rabbitmqctl set_policy -p /liuss --apply-to all liuss-all-policy "^" '{"ha-mode":"nodes","ha-params":["rabbit@vm-10-112-30-103","rabbit@vm-10-112-30-101","rabbit@vm-10-112-30-102"]}'
rabbitmqctl set_policy -p /zhou --apply-to all zhou-all-policy "^" '{"ha-mode":"nodes","ha-params":["rabbit@vm-10-112-30-102","rabbit@vm-10-112-30-103","rabbit@vm-10-112-30-101"]}'
rabbitmqctl set_policy -p /xmm --apply-to all xmm-all-policy "^" '{"ha-mode":"nodes","ha-params":["rabbit@vm-10-112-30-101","rabbit@vm-10-112-30-102","rabbit@vm-10-112-30-103"]}'

i、步骤9

恢复生产者和消费者进程

5

网络分区自动处理自动处理大概意思就是通过配置一些参数,RabbitMQ根据预设的参数进行处理,但是个人还是建议手动处理,可控,这里只是说一下三种方式,详细的解释可读:《RabbitMQ实战指南》或者官网查看. 1、ignore模式

发生网络分区时,不做任何动作,需要人工介入;

人工介入就按:5、网络分区之手动处理 处理

rabbitmq.config中增加如下配置,默认不加就是这种模式

a4c8391692bec99ec63f4fb1c786a5c0.png 2、pause-minority模式 对于对等分区的处理不够优雅(比如每个分区的节点一样多),可能会关闭所有的节点.  一般情况下,可应用于非跨机架、奇数节点数的集群中; 36af6f99c7b9fd805636d1713d898675.png 3、pause-if-all-down模式 对于受信节点的选择尤为考究,尤其是在集群中所有节点硬件配置相同的情况下. 此处模式可以处理对等分区的情形 7656a7038b0ca83e23a26a90768a4c7a.png
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值