对于RabbitMQ的节点来说,有单节点模式和集群模式两种,其中集群模式又分为普通集群模式和镜像队列集群模式,在《RabbitMQ集群架构搭建与高可用性实现》文中,介绍了RabbitMQ的集群创建步骤方法。而镜像队列集群模式的搭建步骤和普通集群模式是基本相同的,唯一不同的是,镜像队列集群模式,多了一步配置policy的步骤。本文主要介绍镜像队列的原理及实现。

1. 创建镜像队列模式

注意,到此步骤,我们假设是你已经创建好了RabbitMQ集群。

1.1 增加镜像队列的Policy

打开你的RabbitMQ管理首页,在Admin->Policy链接下开始创建Policy:

  • Name: 你配置的Policy名称;
  • Pattern: 匹配模式,图片的是匹配testMirror开头的交换机和队列;
  • Priority: 优先级;
  • Definition: 一些模式的定义,RabbitMQ已经列出了以下常见的模式定义。ha-mode是指定镜像队列的模式,有效值为all/exactly/nodes。其中all表示在集群中所有的节点上进行镜像;exactly表示在指定个数的节点上进行镜像,节点的个数由ha-params指定;nodes表示在指定的节点上进行镜像,节点名称通过ha-params指定。ha-sync-mode为指定镜像队列中消息的同步方式,有效值为automatic(自动同步),manually(手动同步);默认是manually,请注意一定要记得设置为automatic(自动同步),否则消息在镜像队列中是不会自动同步的(即普通集群模式),即新节点加入时不会自动同步消息和元数据,只能通过命令手动去同步。

1.2 代码声明交换机、队列、绑定等

1.3 查看镜像队列是否声明成功

查看你刚声明的队列的详情:

可以看到,ha-mode、node、salve等属性都已经创建成功。

2. 镜像队列说明

2.1 关于node节点

queue有master节点和slave节点。 要强调的是,在RabbitMQ中master和slave是针对一个queue而言的,而不是一个node作为所有queue的master,其它node作为slave。一个queue第一次创建的node为它的master节点,其它node为slave节点。

2.2 镜像队列服务提供方式


如上图所示,在镜像队列集群模式中,对某个queue来说,只有master对外提供服务,而其他slave只提供备份服务,在master所在节点不可用时,选出一个slave作为新的master继续对外提供服务。

无论客户端的请求打到master还是slave最终数据都是从master节点获取。当请求打到master节点时,master节点直接将消息返回给client,同时master节点会通过GM(Guaranteed Multicast)协议将queue的最新状态广播到slave节点。GM保证了广播消息的原子性,即要么都更新要么都不更新。

当请求打到slave节点时,slave节点需要将请求先重定向到master节点,master节点将将消息返回给client,同时master节点会通过GM协议将queue的最新状态广播到slave节点。

所以,多个客户端连接不同的镜像队列不会产生同一message被多次接受的情况。

2.3 RabbitMQ集群处理新增节点

如果有新节点加入,RabbitMQ不会同步之前的历史数据,新节点只会复制该节点加入到集群之后新增的消息。
既然master节点退出集群会选一个slave作为master,那么如果不幸选中了一个刚刚加入集群的节点怎么办?那消息不就丢了吗?这里您可以把心放到肚子里,RabbitMQ集群内部会维护节点的状态是否已经同步,使用rabbitmqctl的synchronised_slave_pids参数,就可以查看状态。如果slave_pids和synchronised_slave_pids里面的节点是一致的,那说明全都同步了;如果不一致很容易比较出来哪些还没有同步,集群只会在“最老”的slave节点之间选一个出来作为新的master节点。另外对于node节点的重启也是按照新节点来处理的。

2.4 镜像队列注意点

  • 镜像队列不能作为负载均衡使用,因为每个声明和消息操作都要在所有节点复制一遍。
  • ha-mode参数和durable declare对exclusive队列都不生效,因为exclusive队列是连接独占的,当连接断开,队列自动删除。所以实际上这两个参数对exclusive队列没有意义。
  • 每当一个节点加入或者重新加入(例如从网络分区中恢复回来)镜像队列,之前保存的队列内容会被清空。
  • 对于镜像队列,客户端basic.publish操作会同步到所有节点;而其他操作则是通过master中转,再由master将操作作用于salve。比如一个basic.get操作,假如客户端与slave建立了TCP连接,首先是slave将basic.get请求发送至master,由master备好数据,返回至slave,投递给消费者。

2.5 镜像队列的故障恢复

假设两个节点(A和B)组成一个镜像队列。

  • 场景1:A先停,B后停。 该场景下B是master(disk节点,A是ram),只要先启动B,再启动A即可。或者先启动A,再在30秒之内启动B即可恢复镜像队列。
  • 场景2: A, B同时停。 该场景可能是由掉电等原因造成,只需在30秒之内连续启动A和B即可恢复镜像队列。
  • 场景3:A先停,B后停,且A无法恢复。 该场景是场景1的加强版,因为B是master,所以等B起来后,在B节点上调用rabbitmqctl forget_cluster_node A,解除与A的cluster关系,再将新的slave节点加入B即可重新恢复镜像队列。
  • 场景4:A先停,B后停,且B无法恢复。 该场景是场景3的加强版,比较难处理,早在3.1.x时代之前貌似都没什么好的解决方法,但是现在已经有解决方法了,在3.4.2版本亲测有效(我们当前使用的是3.3.5)。因为B是master,所以直接启动A是不行的,当A无法启动时,也就没办法在A节点上调用rabbitmqctl forget_cluster_node B了。新版本中,forget_cluster_node支持–offline参数,offline参数允许rabbitmqctl在离线节点上执行forget_cluster_node命令,迫使RabbitMQ在未启动的slave节点中选择一个作为master。当在A节点执行rabbitmqctl forget_cluster_node –offline B时,RabbitMQ会mock一个节点代表A,执行forget_cluster_node命令将B剔出cluster,然后A就能正常启动了。最后将新的slave节点加入A即可重新恢复镜像队列。
  • 场景5: A先停,B后停,且A、B均无法恢复,但是能得到A或B的磁盘文件。 该场景是场景4的加强版,更加难处理。将A或B的数据库文件(默认在$RABBIT_HOME/var/lib目录中)拷贝至新节点C的目录下,再将C的hostname改成A或B的hostname。如果拷过来的是A节点磁盘文件,按场景4处理方式;如果拷过来的是B节点磁盘文件,按场景3处理方式。最后将新的slave节点加入C即可重新恢复镜像队列。
  • 场景6:A先停,B后停,且A、B均无法恢复,且无法得到A或B的磁盘文件。 洗洗睡吧,该场景下已无法恢复A、B队列中的内容了。

以上内容就是RabbitMQ镜像队列原理分析的全部内容了,谢谢你阅读到了这里!

Author:zhaoyh

RabbitMQ镜像队列原理分析相关推荐

  1. RabbitMQ + 镜像队列 + HAProxy 实现负载均衡的集群

    RabbitMQ + 镜像队列 + HAProxy 实现负载均衡的集群 一.集群管理(RabbitMQ扩容) 1. 环境介绍 hostname ip mq1 192.168.80.16 mq2 192 ...

  2. RabbitMQ 的延时队列和镜像队列原理与实战

    在阿里云栖开发者沙龙PHP技术专场上,掌阅资深后端工程师.掘金小测<Redis深度历险>作者钱文品为大家介绍了RabbitMQ的延时队列和镜像队列的原理与实践,重点比较了RabbitMQ提 ...

  3. RabbitMQ镜像队列实现原理

    一.镜像队列使用 1.镜像队列作用 ​ RabbitMQ默认集群模式,并不包管队列的高可用性,尽管队列信息,交换机.绑定这些可以复制到集群里的任何一个节点,然则队列内容不会复制,固然该模式解决一项目组 ...

  4. rabbitmq——镜像队列

    转自:http://my.oschina.net/hncscwc/blog/186350?p=1 1. 镜像队列的设置 镜像队列的配置通过添加policy完成,policy添加的命令为: rabbit ...

  5. 详解SpringCloud中RabbitMQ消息队列原理及配置,一篇就够!

    作者:kosamino cnblogs.com/jing99/p/11679426.html 一.MQ用途 1.同步变异步消息 场景:用户下单完成后,发送邮件和短信通知. 运用消息队列之后,用户下单完 ...

  6. RabbitMQ镜像队列与负载均衡

    镜像队列 RabbitMQ集群是由多个broker节点构成的,那么从服务的整体可用性上来讲,该集群对于单点失效是有弹性的,但是同时也需要注意:尽管exchange和binding能够在单点失效问题上幸 ...

  7. RabbitMQ延时队列原理讲解

    RabbitMQ延时消息队列 延时队列介绍 延时队列即放置在该队列里面的消息是不需要立即消费的,而是等待一段时间之后取出消费. 那么,为什么需要延迟消费呢?我们来看以下的场景 网上商城下订单后30分钟 ...

  8. Netty技术细节源码分析-MpscLinkedQueue队列原理分析

    本文的github地址:点此 该文所涉及的netty源码版本为4.1.6. MpscLinkedQueue是什么 在Netty的核心中的核心成员NioEventLoop中,其中任务队列的实现taskQ ...

  9. RabbitMQ集群原理介绍

    文章目录 一.RabbitMQ默认集群原理 1. RabbitMQ集群元数据的同步 2. 为何RabbitMQ集群仅采用元数据同步的方式 3. RabbitMQ集群发送/订阅消息的基本原理 4. 客户 ...

最新文章

  1. linux驱动编程入门实例
  2. php option如何循环每一个值,Js 在option ={ data:[]}中怎么使用循环;
  3. 自动输入runas密码的方法
  4. 白话Elasticsearch56-数据建模之 Path Hierarchy Tokenizer 对文件系统进行数据建模以及文件搜索
  5. 图的基本操作实现(数据结构实验)
  6. 页面自动刷新,页面自动跳转
  7. SAP License:自动过账科目设置
  8. python游戏房间_Python House冒险-如果已经进入一个房间,如何给出不同的输出
  9. 大型网络之---公司内部局域网
  10. 搜索的逻辑即是用户的逻辑
  11. 有没有一款桌面便签软件,可以手机电脑都能使用的?
  12. 胡说八道设计模式—观察者模式
  13. 如何用Mindmanager画思维导图
  14. 买卖股票的最佳时机——力扣121题
  15. iphone、ipad机型分辨率
  16. 操作系统第七、八章习题
  17. 神经网络实现---SSD
  18. 智能座舱全舱感知系统SCSS
  19. 如何安装node.js
  20. 【记录】河北张家口人事档案所在查询 以及【报到证】补办

热门文章

  1. 网络摄像头Androi端显示(mjpeg)源码分析
  2. java blackjack card game_Java BlackJack Game Ace值
  3. RL(Chapter 5): Blackjack (二十一点)
  4. Premiere视频片段剪辑、添加音乐、添加字幕
  5. 维乐坐垫与艺术创想完美融合,让艺术点亮产品灵光
  6. CentOS7.5搭建Heartbeat+DRBD+NFS高可用共享存储
  7. 强大的iOS开发必备工具
  8. Android开机启动检测和连接wifi检测
  9. nokia s40 java软件_诺基亚S40手机实现后台教程
  10. 全国高等教师资格证考试复习笔记-高等教育学(1)-教育学概述