集群成员之间的网络连接故障会影响客户机操作的数据一致性和可用性(如CAP定理)。由于不同的应用程序对一致性有不同的要求,并且对不可用性的容忍程度不同,所以可以使用不同的的分区处理策略。

1.检测网络分区

如果一个节点在一段时间内(默认是60秒)无法与对等端节点联系,则节点将认为其对等节点是否已关闭。如果两个节点重新接触,都认为另一个已关闭,则这些节点将确定已发生分区。将以如下形式记录到RabbitMQ日志:

2020-05-18 06:55:37.324 [error] <0.341.0> Mnesia(rabbit@warp10): ** ERROR ** mnesia_event got {inconsistent_database, running_partitioned_network, rabbit@hostname2}

分区状态判定:可以通过服务器日志、HTTP API(用于监视)和CLI命令进行标识:

rabbitmq-diagnostics cluster_status

rabbitmq-diagnostics cluster_status通常会为分区显示一个空列表(经过实际的测试会显示如:Node rabbit@rabbit1 cannot communicate with rabbit@rabbit2):

官网示例:

rabbitmq-diagnostics cluster_status
# => Cluster status of node rabbit@warp10 ...
# => Basics
# =>
# => Cluster name: local.1
# =>
# => ...edited out for brevity...
# =>
# => Network Partitions
# =>
# => (none)
# =>
# => ...edited out for brevity...

分区状态查看:如果网络分区已经发生,则分区信息将按展示如下信息:

rabbitmqctl cluster_status
# => Cluster status of node rabbit@warp10 ...
# => Basics
# =>
# => Cluster name: local.1
# =>
# => ...edited out for brevity...
# =>
# => Network Partitions
# =>
# => Node flopsy@warp10 cannot communicate with hare@warp10
# => Node rabbit@warp10 cannot communicate with hare@warp10

HTTP API将返回 GET /api/nodes端点中分区下的每个节点信息;如果发生分区,web管理页面上将显示警告信息;

2.网络分区期间的行为

当网络分区发生后,两个(或更多个)分区双方都认为对方已经崩溃。这种情况被称为分裂集群(split-brain),队列、绑定、交换器可以单独创建或删除。

经典的镜像队列将在分区的每一次都有一个master队列,而且两侧都独立运行。

除非配置分区处理策略(如:pause_minority),否则即使在网络连接恢复后分区仍将继续存在(因为默认策略是ignore)。

3.由挂起和恢复引起的分区

当我们提到网络分区时,实际上分区是指集群的不同节点可以在没有任何节点故障的情况下中断通信。除了网络故障,挂起和恢复整个操作系统在针对运行的集群节点使用时也可能导致分区-由于挂起的节点不会认为自己已失败,甚至不会停止,但是集群中其它节点会认为他已经挂掉了。

虽然你可以通过在笔记本电脑上运行集群节点并通过关闭它的盖子来挂起,但是发生这种情况最常见的原因是虚拟机被hypervisor挂起。

虽然在虚拟化环境或容器中运行RabbitMQ集群很好,但是要确保VM在运行时没有挂起。

请注意,一些虚拟化功能(如:将虚拟机从一台主机迁移到另一台主机)往往会导致虚拟机被挂起。

由suspend和resume引起的分区往往是不对称的-挂起的节点不一定会看到其它节点已关闭,但会被集群的其余部分视为已关闭。这是pause_minority模式特别有用。

4.手动恢复网络分区(Recovering from a split-brain)

要恢复分区,首先选择一个你最信任的分区,此分区将成为(系统状态、模式、消息、队列、交换器)受信任的主分区,在其它分区上的任何更改将会丢失。

手动恢复分区有两种方法:

  • A分区受信任,停止其它分区的所有节点,然后启动所有节点。当它们重新加入集群时,它们将从受信任分区恢复状态。
#停止节点(包括RabbitMQ应用和Erlang VM虚拟机)
rabbitmqctl stop
#启动节点
rabbitmq-server -detached

最后,你应该重启信任分区的所有节点,目的是为了清除警告(实测不用重启也可以清除受信任分区的警告信息)

  • 停止所有分区的节点,并启动所有的节点(启动的第一个节点必须是受信任分区的节点)
#停止节点(包括RabbitMQ应用和Erlang VM虚拟机)
rabbitmqctl stop
#启动节点
rabbitmq-server -detached
5.网络分区处理策略

RabbitMQ提供了四种方法自动处理网络分区(默认行为被称为ignore模式,需手动处理):

  • ignore模式

  • pause-minority模式

  • pause-if-all-down模式

  • autoheal模式

ignore模式在/etc/rabbitmq/advanced.config中的配置:

 [{rabbit, [{cluster_partition_handling, ignore}]}].

或在/etc/rabbitmq/rabbitmq.conf中的配置:

cluster_partition_handling = ignore

在pause-minority模式下,当发生网络分区时,集群的节点在观察到某些节点down掉时,会自动检测自身是否处于少数派(即少于或等于节点总数的一半),少数派将会在分区发生时自动关闭,并且在分区结束时自动启动。这里的关闭是只RabbitMQ 应用程序关闭,对应CTL命令是rabbitmqctl stop_app,而Erlang VM并不关闭。处于关闭的节点会每秒检测一次是否可以连通到剩余的集群中,如果可以则启动自身的应用,这种配置防止了网络分区,因此能够自动从网络分区恢复而不出现不一致。

需要注意的是RabbitMQ也会关闭不是严格意义上的大多数,比如在一个集群中只有两个节点的时候并不适合pause-minority模式,因为由于其中任何一个节点失败而发生网络分区时,两个节点都会关闭。当网络恢复时,有可能两个节点会自动启动恢复网络分区,也有可能保持关闭状态。然而如果集群中的节点远大于两个时,pause-minority模式比ignore模式更加可靠,特别是网络分区通常是由于单个节点网络故障而脱离原分区引起的。

在/etc/rabbitmq/advanced.config配置文件中的配置:

 [{rabbit, [{cluster_partition_handling, pause_minority}]}].

或在/etc/rabbitmq/rabbitmq.conf中的配置:

cluster_partition_handling = pause_minority

在pause-if-all-down模式下,RabbitMQ会自动关闭不能和list中节点通信的节点。语法为{pause-if-all-down,[nodes],ignore|autoheal},其中[nodes]就是前面所说的list。如果一个节点与list中的所有节点都无法通信时,关闭其自身。如果list中的所有节点都down时,其余节点是正常的话,也会根据这个规则关闭其自身。此时集群中所有的节点会关闭。如果某个节点可以和list中的节点恢复通信,那么会启动其自身的RabbitMQ应用,慢慢的集群可以恢复。

有两种配置如下:

 [{rabbit, [{cluster_partition_handling, {pause_if_all_down,  ['rabbit@node1'], autoheal}}]}].

 [{rabbit, [{cluster_partition_handling, {pause_if_all_down,  ['rabbit@node1'], ignore}}]}].

或在/etc/rabbitmq/rabbitmq.conf中的配置:

## pause_if_all_down strategy require additional configuration
# cluster_partition_handling = pause_if_all_down## Recover strategy. Can be either 'autoheal' or 'ignore'
# cluster_partition_handling.pause_if_all_down.recover = ignore## Node names to check
# cluster_partition_handling.pause_if_all_down.nodes.1 = rabbit@localhost
# cluster_partition_handling.pause_if_all_down.nodes.2 = hare@localhost

配置中会有ignore和autoheal模式设置,考虑会有这样一种情况,有两个节点在A、B在机架M上,节点C、D在机架N上,此时机架M和N的通信出现了异常,如果使用pause-minority模式的话会关闭所有的节点,如果此时采用pause-if-all-down,list中配置成[A,C]的话,集群中的四个节点都不会关闭,但是会形成两个分区,此时就需要使用ignore和autoheal来指引如何处理这种分区情况。

在autoheal模式下,当认为发生网络分区时,RabbitMQ会自动决定一个获胜的分区,然后重启不在这个分区中的节点以恢复网络分区。一个获胜的分区是指客户端连接最多的一个分区。如果产生平局,即两个或者多个分区的客户端连接数一样多,那么节点数最多的一个分区就是获胜的分区。如果此时节点数一样多,将以一种特殊的方式来挑选获胜分区。

 [{rabbit, [{cluster_partition_handling, autoheal}]}].

rabbitmq.conf配置文件示例地址:https://github.com/rabbitmq/rabbitmq-server/blob/master/docs/rabbitmq.conf.example

rabbitmq.conf配置文件在服务端的位置是/etc/rabbitmq/rabbitmq.conf

6.如何关闭端口号或者域名
封单个IP的命令:
iptables -I INPUT -s 124.115.0.199 -j DROP解封单个IP的命令:
iptables -D INPUT -s 124.115.0.199 -j DROP封整个段的命令:
iptables -I INPUT -s 194.42.0.0/8 -j DROP解封整个段的命令:
iptables -D INPUT -s 194.42.0.0/8 -j DROP封指定的端口:
iptables -A INPUT -p tcp --dport 80 -j DROP解封指定的端口:
iptables -A INPUT -p tcp --dport 80 -j ACCEPT#一键清空所有规则
iptables -F清空:
iptables -D INPUT 数字查看:
iptables -L -n

GitHub地址:https://github.com/mingyang66/spring-parent/tree/master/doc/rabbitmq

RabbitMQ学习笔记:集群和网络分区(Network Partitions)相关推荐

  1. RabbitMQ学习之集群模式

    由于RabbitMQ是用erlang开发的,RabbitMQ完全依赖Erlang的Cluster,因为erlang天生就是一门分布式语言,集群非常方便,但其本身并不支持负载均衡.Erlang的集群中各 ...

  2. Hadoop学习笔记-集群部署

    前期准备 使用三台主机,每台安装好JDK和Hadoop 参考:Hadoop学习笔记–单台安装 同步小技巧 scp–rsync–编写xsync scp是主机之间安全拷贝数据的工具,一般的语法为 scp ...

  3. RabbitMQ学习之集群镜像模式配置

    1.增加负载均衡器 关于负载均衡器,商业的比如F5的BIG-IP,Radware的AppDirector,是硬件架构的产品,可以实现很高的处理能力.但这些产品昂贵的价格会让人止步,所以我们还有软件负载 ...

  4. (转)RabbitMQ学习之集群部署

    http://blog.csdn.net/zhu_tianwei/article/details/40931971 我们先搭建一个普通集群模式,在这个模式基础上再配置镜像模式实现高可用,Rabbit集 ...

  5. Rabbitmq学习笔记(尚硅谷2021)

    Rabbitmq学习笔记 (尚硅谷) 1.MQ 的概念 1.1 什么是 MQ? 1.2 为什么要用 MQ? 削峰 解耦 异步 1.3 MQ 的分类 ActiveMQ Kafka RocketMQ Ra ...

  6. 从零开始搭建高可用RabbitMQ镜像模式集群

    文章目录 RabbitMQ集群模式搭建 准备工作 选取任意一个节点作为master节点, 进行文件同步, 我这里选择138作为master节点 组成集群 配置镜像队列(设置镜像队列策略) 集群配置参数 ...

  7. Rabbitmq学习笔记教程-尚硅谷

    Rabbitmq学习笔记 (尚硅谷) 尚硅谷 rabbitmq 教程 1.MQ 的概念 1.1 什么是 MQ? 存放消息的队列,互联网架构中常见的一种服务与服务之间通信的方式. 1.2 为什么要用 M ...

  8. RabbitMQ 学习笔记

    RabbitMQ 学习笔记 RabbitMQ 学习笔记 1. 中间件 1.1 什么是中间件 1.2 为什么要使用消息中间件 1.3 中间件特点 1.4 在项目中什么时候使用中间件技术 2. 中间件技术 ...

  9. RabbitMQ学习笔记(高级篇)

    RabbitMQ学习笔记(高级篇) 文章目录 RabbitMQ学习笔记(高级篇) RabbitMQ的高级特性 消息的可靠投递 生产者确认 -- confirm确认模式 生产者确认 -- return确 ...

最新文章

  1. uva232corssword answers模拟
  2. 使用TPU的注意事项
  3. 争时金融java_Java高并发编程基础之AQS
  4. Java案例:压缩与解压缩文件
  5. M1卡说明及使用proxmark3破解方法
  6. centos 7 64位虚机上android4环境运行
  7. html5 游戏营销,五大H5游戏营销成功案例,你都玩过了吗?
  8. [转帖] 一个老乞丐的一句话,震惊全中国人!
  9. 微软自带dns服务器,win10微软设置哪个DNS服务器地址最快
  10. ◎◎首都机场大巴最新路线时刻表◎◎
  11. 人工智能的示例——八皇后问题
  12. thinningopencv
  13. Visionpro棋盘格校正
  14. 72 ----直纹面、二次直纹面、单叶双曲面、双曲抛物面
  15. 腾讯云服务器购买详细流程(手把手教程)
  16. Javascript日期的Format与Parse
  17. 计算机的硬件系统和软件系统
  18. LittleVGL(LVGL)学习笔记——PC 模拟器的安装和使用(CodeBlocks)
  19. Java8新特性-使用Stream流来实现递归遍历树形结构(案例)
  20. 基于wpa_supplicant库的WIFI连接功能实现--wpa_cli命令解析

热门文章

  1. QT--多TCP客户端
  2. css 中的zoom,对CSS中zoom属性的总结
  3. linux系统安装在u盘
  4. 马尔可夫决策过程(Markov Decision Process, MDP)
  5. 【数据库】多表查询二----嵌套查询(子查询)
  6. 用python写vip电影进行地址解析
  7. 2018上半年软件设计师上午试题参考答案
  8. vuex刷新state数据丢失问题
  9. Redis C 语言客户端 hiredis 的使用
  10. C语言 图形任意多次平移、旋转、缩放和对称的变换方案