RabbitMQ 集群原理和完善

一、RabbitMQ集群方案的原理

RabbitMQ这款消息队列中间件产品本身是基于Erlang编写,Erlang语言天生具备分布式特性(通过同步Erlang集群各节点的magic cookie来实现)。

因此,RabbitMQ天然支持Clustering。这使得RabbitMQ本身不需要像ActiveMQ、Kafka那样通过ZooKeeper分别来实现HA方案和保存集群的元数据。集群是保证可靠性的一种方式,同时可以通过水平扩展以达到增加消息吞吐量能力的目的。下面先来看下RabbitMQ集群的整体方案:

RabbitMQ 集群原理和完善

上面图中采用三个节点组成了一个RabbitMQ的集群,Exchange A(交换器,对于RabbitMQ基础概念不太明白的童鞋可以看下基础概念)的元数据信息在所有节点上是一致的,而Queue(存放消息的队列)的完整数据则只会存在于它所创建的那个节点上。,其他节点只知道这个queue的metadata信息和一个指向queue的owner node的指针。

(1)RabbitMQ集群元数据的同步

RabbitMQ集群会始终同步四种类型的内部元数据(类似索引): a.队列元数据:队列名称和它的属性; b.交换器元数据:交换器名称、类型和属性; c.绑定元数据:一张简单的表格展示了如何将消息路由到队列; d.vhost元数据:为vhost内的队列、交换器和绑定提供命名空间和安全属性; 因此,当用户访问其中任何一个RabbitMQ节点时,通过rabbitmqctl查询到的queue/user/exchange/vhost等信息都是相同的。

(2)为何RabbitMQ集群仅采用元数据同步的方式

我想肯定有不少同学会问,想要实现HA方案,那将RabbitMQ集群中的所有Queue的完整数据在所有节点上都保存一份不就可以了么?(可以类似MySQL的主主模式嘛)这样子,任何一个节点出现故障或者宕机不可用时,那么使用者的客户端只要能连接至其他节点能够照常完成消息的发布和订阅嘛。

我想RabbitMQ的作者这么设计主要还是基于集群本身的性能和存储空间上来考虑。

第一,存储空间,如果每个集群节点都拥有所有Queue的完全数据拷贝,那么每个节点的存储空间会非常大,集群的消息积压能力会非常弱(无法通过集群节点的扩容提高消息积压能力);

第二,性能,消息的发布者需要将消息复制到每一个集群节点,对于持久化消息,网络和磁盘同步复制的开销都会明显增加。

(3)RabbitMQ集群发送/订阅消息的基本原理

RabbitMQ集群的工作原理图如下:

RabbitMQ 集群原理和完善

场景1:客户端直接连接队列所在节点

如果有一个消息生产者或者消息消费者通过amqp-client的客户端连接至节点1进行消息的发布或者订阅,那么此时的集群中的消息收发只与节点1相关,这个没有任何问题;如果客户端相连的是节点2或者节点3(队列1数据不在该节点上),那么情况又会是怎么样呢?

场景2:客户端连接的是非队列数据所在节点

如果消息生产者所连接的是节点2或者节点3,此时队列1的完整数据不在该两个节点上,那么在发送消息过程中这两个节点主要起了一个路由转发作用,根据这两个节点上的元数据(也就是上文提到的:指向queue的owner node的指针)转发至节点1上,最终发送的消息还是会存储至节点1的队列1上。

同样,如果消息消费者所连接的节点2或者节点3,那这两个节点也会作为路由节点起到转发作用,将会从节点1的队列1中拉取消息进行消费。

一、RabbitMQ集群完善

RabbitMQ 集群原理和完善

可以根据这个架构图,做一些RabbitMQ集群完善,主要是将内存节点作为负载,磁盘节点作为存储。

更改集群节点类型:

rabbitmqctl stop_app

rabbitmqctl change_cluster_node_type ram
rabbitmqctl change_cluster_node_type disc

rabbitmqctl start_app

rabbitmqctl cluster_status

如果出现错误:

Error: unable to connect to node rabbit@manager1: nodedown

解决方式:

/sbin/service rabbitmq-server stop
/sbin/service rabbitmq-server start
rabbitmqctl status

如果要将节点移除集群,则在本节点上执行:

rabbitmqctl stop_app &&
rabbitmqctl reset &&
rabbitmqctl start_app

然后在主节点执行:

rabbitmqctl forget_cluster_node rabbit@manager3

节点加入集群命令:

rabbitmqctl join_cluster rabbit@manager3 --ram
rabbitmqctl join_cluster rabbit@manager3 --disc

参考资料:

Original: https://www.cnblogs.com/xishuai/p/rabbitmq-cluster.html
Author: 田园里的蟋蟀
Title: RabbitMQ 集群原理和完善

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/540193/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 如何解决java.sql.SQLException: Column ‘ XXX ‘ not found

    在我们编写代码时,可能会遇到这种报错,报错的意思是找不到列XXX(questionId). 出现这种报错的可能原因有三个: 1.数据库表里缺少XXX(questionId)这一列….

    Java 2023年6月8日
    097
  • 事件的监听与发布

    有些时候,我们希望某件事情发生的时候能够触发一个事件,让这个事件帮我们做些事情。比如,在晚上十一点到晚上十二点这段时间,假如还有人在使用我们的软件,我们就触发一个事件播放一首美妙的…

    Java 2023年6月5日
    072
  • springboot分析——与其他组件的整合(druid/mybatis)

    springboot本身提供了许多自动配置,帮助开发者提供开发效率,当然如果我们有一些个性化的需求,springboot 也提供了良好的扩展,只需要配置starter依赖或者简单的…

    Java 2023年5月30日
    066
  • 第三周总结-SpringMvc+RESTful学习

    java;gutter:true;</p> <h2>1,SpringMVC概述</h2> <p>学习SpringMVC我们先来回顾下…

    Java 2023年6月7日
    074
  • JDK8新特性

    1、语法:完整的Lambda表达式由三部分组成:参数列表、箭头、声明语句 2、绝大多数情况,编译器都可以从上下文环境中推断出lambda表达式的参数类型,所以参数可以省略 3、当l…

    Java 2023年5月30日
    059
  • Java开发学习(十二)—-基于注解开发依赖注入

    Spring为了使用注解简化开发,并没有提供 &#x6784;&#x9020;&#x51FD;&#x6570;&#x6CE8;&#x…

    Java 2023年5月29日
    077
  • 非确定的自动机NFA确定化为DFA

    摘要: 在编译系统中,词法分析阶段是整个编译系统的基础。对于单词的识别,有限自动机FA是一种十分有效的工具。有限自动机由其映射f是否为单值而分为确定的有限自动机DFA和非确定的有限…

    Java 2023年6月7日
    065
  • Java基础-多线程学习目录

    多线程学习目录 Java多线程并发编程一览笔录 什么时候使用CountDownLatch Java并发学习系列-绪论 God, Grant me the SERENITY, to …

    Java 2023年5月29日
    080
  • [转帖]Nginx(九)nginx的favico.ico

    404. 抱歉,您访问的资源不存在。 可能是网址有误,或者对应的内容被删除,或者处于私有状态。 代码改变世界,联系邮箱 contact@cnblogs.com 园子的商业化努力-困…

    Java 2023年5月30日
    075
  • idea创建maven项目速度慢?别急,这有三种方案

    1 问题 Intellij idea是一款非常强大的编辑器,可以很方便地帮我们创建maven项目,有用过的同学应该都深有体会,但我们经常会遇到一个困扰,那就是用idea创建mave…

    Java 2023年6月5日
    0121
  • Java中的static关键字

    java中的static关键字1. 概述假设有一个学生类,它的数据成员有姓名、年龄、学号、教室,对于在同一个班的同学来讲,每个同学的姓名、年龄、学号或许都是不一样的,但是教室肯定是…

    Java 2023年5月29日
    071
  • 关于Non-static method xx cannot be referenced from a static context的分析与解决方案

    关于static method的解释 想要解决上面的报错,我们首先需要了解什么叫做static method(静态方法)。 静态方法为类所有,一般情况下我们通过类来使用(而对于不加…

    Java 2023年6月16日
    063
  • Java基础 变量名的开头可以使用$

    JDK :OpenJDK-11 OS :CentOS 7.6.1810 IDE :Eclipse 2019‑03 typesetting :Markdown code packag…

    Java 2023年5月29日
    068
  • Android连载42-复习自定义控件

    继承关系 所有的控件都直接或者间接继承自View View是Android中的一种基本的UI组件,可以在屏幕上绘制一块矩形区域 ViewGroup则是一种特殊的View,它可以包含…

    Java 2023年6月13日
    084
  • MyBatis

    一、Mybatis基本使用步骤 1.导入依赖 org.mybatis mybatis 3.5.2 2.配置连接池 db.properties(使用jdbc-mysql驱动) dri…

    Java 2023年6月5日
    088
  • 数据持久化面试题库

    一:你用过的持久层框架有哪些?早期jdbc代码太麻烦,所以出现了很多持久层框架,我使用的有mybatis,hibernate。 二:@OneToMany注解的mappedBy属性有…

    Java 2023年6月5日
    072
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球