RabbitMQ 集群
你可以使用若干个RabbitMQ 节点组成一个 RabbitMQ 集群。集群解决的是扩展性问题。所有的数据和状态都会在集群内所有的节点上被复制,只有queue是例外。默认的情况下,消息只会存在于它被创建的节点上,但是它们在所有节点上可见和可访问。
对于Queue 来说,消息实体只存在于其中一个节点,A、B两个节点仅有相同的元数据,即队列结构。当消息进入A节点的Queue中后,consumer从B节点拉取时,RabbitMQ会临时在A、B间进行消息传输,把A中的消息实体取出并经过B发送给consumer。所以consumer应尽量连接每一个节点,从中取消息。即对于同一个逻辑队列,要在多个节点建立物理Queue。否则无论consumer连A或B,出口总在A,会产生瓶颈。该模式存在一个问题就是当A节点故障后,B节点无法取到A节点中还未消费的消息实体。如果做了消息持久化,那么得等A节点恢复,然后才可被消费;如果没有持久化的话,然后就没有然后了。
因此,在集群环境中,队列只有元数据会在集群的所有节点同步,但队列中的数据只会存在于一个节点,数据没有冗余且容易丢,甚至在durable的情况下,如果所在的服务器节点宕机,就要等待节点恢复才能继续提供消息服务。那既然有这种问题,为什么依然有这个选项呢?官方的说法是:
(1)存储空间:如果集群的每个节点都有每个queue的一个拷贝,那么增加节点将无法增加存储容量。比如,如果一个节点可以存放 1GB 的消息,增加另外两个节点只会增加另外两个拷贝而已。
(2)性能:发布消息,将会将它拷贝其它节点上。如果是持久性消息,那么每个节点上都会触发磁盘操作。你的网络和磁盘负载在每次增加节点时都会增加。
可见,RabbitMQ Clustering 技术不能完全解决HA 问题。单纯的集群只适合于在不需要HA的场景中使用。
一.基于集群+镜像队列的方案
1.配置
多个单独的 RabbitMQ 服务,可以加入到一个集群中,也可以从集群中退出。集群中的 RabbitMQ 服务,使用同样的 Erlang cookie(unix 系统上默认为 /var/lib/rabbitmq/.erlang.cookie)。所有在一个 RabbitMQ 服务中被操作的数据和状态(date/state)都会被同步到集群中的其它节点。
镜像队列的配置通过添加 policy 完成,policy 添加的命令为:
rabbitmqctl set_policy [-p Vhost] Name Pattern Definition [Priority]
-p Vhost: 可选参数,针对指定vhost下的queue进行设置
Name: policy的名称
Pattern: queue的匹配模式(正则表达式)
Definition: 镜像定义,包括三个部分 ha-mode,ha-params,ha-sync-mode
ha-mode: 指明镜像队列的模式,有效值为 all/exactly/nodes
all表示在集群所有的节点上进行镜像
exactly 表示在指定个数的节点上进行镜像,节点的个数由ha-params指定
nodes 表示在指定的节点上进行镜像,节点名称通过ha-params指定
ha-params: ha-mode模式需要用到的参数
ha-sync-mode: 镜像队列中消息的同步方式,有效值为automatic,manually
Priority: 可选参数, policy的优先级
例如,对队列名称以 ’hello‘ 开头的所有队列进行镜像,并在集群的两个节点上完成镜像,policy的设置命令为:
rabbitmqctl set_policy hello-ha "^hello" '{"ha-mode":"exactly","ha-params":2,"ha-sync-mode":"automatic"}'
2.2 HAProxy 和 RabbitMQ 集群
创建 queue 的过程:
LB 将 client request 分发到 node 2,client 创建队列 “NewQueue”,然后开始向其中放入 message。
最终,后端服务会对 node 2 上的 “NewQueue” 创建一个快照,并在一段时间内将其拷贝到node 1 和 3 上。这时候,node2 上的队列是 master Queue,node 1 和 3 上的队列是 slave queue。
假如现在 node2 宕机了:
node 2 不再响应心跳,它会被认为已经被从集群中移出了
node 2 上的 master queue 不再可用
RabbitMQ 将 node 1 或者 3 上的 salve instance 升级为 master instance
假设 master queue 还在 node 2 上,客户端通过 LB 访问该队列:
客户端连接到集群,要访问 “NewQueue” 队列
LB 根据配置的轮询算法将请求分发到一个节点上
假设客户端请求被转到 node 3 上
RabbitMQ 发现 “NewQueue” master node 是 node 2
RabbitMQ 将消息转到 node 2 上
最终客户端成功连接到 node 2 上的 master 队列
可见,这种配置下,2/3 的客户端请求需要重定向,这会造成大概率的访问延迟,但是终究访问还是会成功的。要优化的话,总共有两种方式:
直接连到 master queue 所在的节点,这样就不需要重定向了。但是对这种方式,需要提前计算,然后告诉客户端哪个节点上有 master queue。
尽可能地在所有节点间平均分布队列,减少重定向概率
2.3 镜像队列的负载均衡
使用镜像队列的 RabbitMQ 不支持负载均衡,这是由其镜像队列的实现机制决定的。如前面所述,假设一个集群里有两个实例,记作 rabbitA 和 rabbitB。如果某个队列在rabbitA 上创建,随后在 rabbitB 上镜像备份,那么 rabbitA 上的队列称为该队列的主队列(master queue),其它备份均为从队列。接下来,无论client 访问rabbitA 或 rabbitB,最终消费的队列都是主队列。换句话说,即使在连接时主动连接rabbitB,RabbitMQ的 cluster 会自动把连接转向 rabbitA。当且仅当rabbitA服务down掉以后,在剩余的从队列中再选举一个作为继任的主队列。
如果这种机制是真的(需要看代码最最终确认),那么负载均衡就不能简单地随机化连接就能做到了。要实现轮询,需要满足下面的条件:
队列本身的建立需要随机化,即将队列分布于各个服务器
client 访问需要知道每个队列的主队列保存在哪个服务器
如果某个服务器down了,需要知道哪个从队列被选择成为继任的主队列。
要实现这种方案,首先,在建立一个新队列的时候,Randomiser 会随机选择一个服务器,这样能够保证队列均匀分散在各个服务器(这里暂且不考虑负载)。建立队列后需要在Meta data 里记录这个队列对应的服务器;另外,Monitor Service是关键,它用于处理某个服务器down掉的情况。一旦发生down机,它需要为之前主队列在该服务器的队列重新建立起与服务器的映射关系。
这里会遇到一个问题,即怎么判断某个队列的主队列呢?一个方法是通过rabbitmqctl,如下面的例子:
./rabbitmqctl -p production list_queues pid slave_pids
registration-email-queue <rabbit@mq01.2.1076.0> [<rabbit@mq00.1.285.0>]
registration-sms-queue <rabbit@mq01.2.1067.0> [<rabbit@mq00.1.281.0>]
可以看到pid和slave_pids分别对应主队列所在的服务器和从服务器(可能有多个)。
利用这个命令就可以了解每个队列所在的主服务器了。
参考:
http://www.cnblogs.com/sammyliu/p/4730517.html
分享到:
相关推荐
以上就是RabbitMQ集群环境搭建的主要步骤,通过这些步骤可以在多个服务器之间搭建起一个稳定可靠的RabbitMQ集群。需要注意的是,在实际部署过程中还需要根据实际情况调整配置,并确保网络连接通畅。
本文将深入探讨如何在生产环境中部署RabbitMQ集群,以满足大规模应用的需求。 首先,我们需要理解RabbitMQ集群的基本概念。集群是将多个RabbitMQ节点联合在一起,形成一个单一的逻辑服务。在集群中,消息可以在任何...
kubernetes搭建rabbitmq集群,只需创建好相应的pv即可,无需修改,依次执行
首先,我们来看RabbitMQ集群。RabbitMQ是一款基于AMQP协议的开源消息中间件,由Erlang编程语言实现,以其稳定性和灵活性受到广泛欢迎。在生产环境中,为了提高RabbitMQ的服务可用性和性能,通常会构建RabbitMQ集群。...
### RabbitMQ集群在Linux下的搭建知识点详解 #### 一、实验环境配置 为了搭建一个可靠的RabbitMQ集群,首先需要确保所有的服务器节点都处于相同的网络环境中,并且具有稳定的网络连接。根据提供的信息,本实验环境...
资源包含rabbitmq镜像集群的搭建文档和springboot连接rabbitmq集群的配置方式,供参考
包含k8s下部署rabbitmq集群部署方式的说明,有pv.yaml, svc.yaml, statefulset.yaml
Rabbitmq 集群配置按照图解,步骤很详细及问题说明
1.Docker搭建RabbitMQ集群
综上所述,“rabbitmq集群测试资源”可能包含了创建、配置、监控和故障恢复RabbitMQ集群所需的各种工具和信息,这对于理解和优化RabbitMQ集群的性能和可靠性至关重要。在实际操作中,应根据具体需求和环境调整集群...
RabbitMQ 集群主从安装 RabbitMQ 是一个开源的消息队列系统,使用 Erlang 语言开发,提供了高性能、可扩展的消息队列服务。本文档将详细介绍如何安装 RabbitMQ 集群主从服务,包括安装依赖软件、语言环境 Erlang、...
CentOS7 安装 RabbitMQ 集群 在本节中,我们将介绍如何在 CentOS7 上安装 RabbitMQ 集群。RabbitMQ 是一个流行的开源消息队列服务器,可以用于分布式系统中的消息传递和队列管理。 一、安装 Erlang 运行环境 ...
除了一台刚刚安装完成,纯净版的,没有做任何开...1.192.168.1.61~62是一个rabbitmq集群,这集群,有2台组成集群 2.192.168.1.63~65是一个rabbitmq集群,这集群,有3台组成集群 redis,redis哨兵,redis集群,predixy,twempr
**RabbitMQ 集群搭建详解** 在分布式系统中,消息队列(RabbitMQ)是一种重要的组件,它用于解耦应用之间的通信,提高系统的可扩展性和容错性。RabbitMQ 是基于 AMQP(Advanced Message Queuing Protocol)的开源消息...
标题提到的"RabbitMQ集群 所需的erlang和rabbitmq的rpm包",指的是在构建RabbitMQ集群时,需要先安装Erlang环境,因为RabbitMQ是用Erlang编程语言编写的。Erlang是一种为并发、容错和实时系统设计的编程语言,其强大...
### RabbitMQ集群原理详解 #### 一、RabbitMQ默认集群原理 RabbitMQ是一款开源的消息中间件,基于Erlang语言开发。由于Erlang语言本身的分布式特性,使得RabbitMQ天然支持集群部署,这不仅能够提升系统的可用性和...
在本文档中,我们将深入探讨如何搭建和使用 RabbitMQ 集群。 首先,RabbitMQ 集群的搭建涉及以下关键步骤: 1. **环境准备**:确保所有参与集群的服务器都已安装了 RabbitMQ。每个服务器上的实例应能正常启动。...
【RabbitMQ集群搭建指南】 在企业IT架构中,消息队列(MQ)扮演着至关重要的角色,它能够实现异步处理、解耦系统组件、提高系统吞吐量。RabbitMQ作为开源MQ的佼佼者,凭借其高效、稳定和易扩展的特性,广泛应用于...