(一) 功能和原理

设计集群的目的

  • 允许消费者和生产者在RabbitMQ节点崩溃的情况下继续运行

  • 通过增加更多的节点来扩展消息通信的吞吐量

1 集群配置方式

RabbitMQ可以通过三种方法来部署分布式集群系统,分别是:cluster,federation,shovel

  • cluster:

    • 不支持跨网段,用于同一个网段内的局域网

    • 可以随意的动态增加或者减少

    • 节点之间需要运行相同版本的RabbitMQ和Erlang

  • federation:应用于广域网,允许单台服务器上的交换机或队列接收发布到另一台服务器上交换机或队列的消息,可以是单独机器或集群。federation队列类似于单向点对点连接,消息会在联盟队列之间转发任意次,直到被消费者接受。通常使用federation来连接internet上的中间服务器,用作订阅分发消息或工作队列。

  • shovel:连接方式与federation的连接方式类似,但它工作在更低层次。可以应用于广域网。

2 节点类型

  • RAM node:内存节点将所有的队列、交换机、绑定、用户、权限和vhost的元数据定义存储在内存中,好处是可以使得像交换机和队列声明等操作更加的快速。

  • Disk node:将元数据存储在磁盘中,单节点系统只允许磁盘类型的节点,防止重启RabbitMQ的时候,丢失系统的配置信息。

问题说明: RabbitMQ要求在集群中至少有一个磁盘节点,所有其他节点可以是内存节点,当节点加入或者离开集群时,必须要将该变更通知到至少一个磁盘节点。如果集群中唯一的一个磁盘节点崩溃的话,集群仍然可以保持运行,但是无法进行其他操作(增删改查),直到节点恢复。 
解决方案:设置两个磁盘节点,至少有一个是可用的,可以保存元数据的更改。

3 Erlang Cookie

Erlang Cookie是保证不同节点可以相互通信的密钥,要保证集群中的不同节点相互通信必须共享相同的Erlang Cookie。具体的目录存放在/var/lib/rabbitmq/.erlang.cookie。

说明: 这就要从rabbitmqctl命令的工作原理说起,RabbitMQ底层是通过Erlang架构来实现的,所以rabbitmqctl会启动Erlang节点,并基于Erlang节点来使用Erlang系统连接RabbitMQ节点,在连接过程中需要正确的Erlang Cookie和节点名称,Erlang节点通过交换Erlang Cookie以获得认证。

4 镜像队列

功能和原理 
RabbitMQ的Cluster集群模式一般分为两种,普通模式和镜像模式。

  • 普通模式:默认的集群模式,以两个节点(rabbit01、rabbit02)为例来进行说明。对于Queue来说,消息实体只存在于其中一个节点rabbit01(或者rabbit02),rabbit01和rabbit02两个节点仅有相同的元数据,即队列的结构。当消息进入rabbit01节点的Queue后,consumer从rabbit02节点消费时,RabbitMQ会临时在rabbit01、rabbit02间进行消息传输,把A中的消息实体取出并经过B发送给consumer。所以consumer应尽量连接每一个节点,从中取消息。即对于同一个逻辑队列,要在多个节点建立物理Queue。否则无论consumer连rabbit01或rabbit02,出口总在rabbit01,会产生瓶颈。当rabbit01节点故障后,rabbit02节点无法取到rabbit01节点中还未消费的消息实体。如果做了消息持久化,那么得等rabbit01节点恢复,然后才可被消费;如果没有持久化的话,就会产生消息丢失的现象。

  • 镜像模式:将需要消费的队列变为镜像队列,存在于多个节点,这样就可以实现RabbitMQ的HA高可用性。作用就是消息实体会主动在镜像节点之间实现同步,而不是像普通模式那样,在consumer消费数据时临时读取。缺点就是,集群内部的同步通讯会占用大量的网络带宽。

实现机制 
镜像队列实现了RabbitMQ的高可用性(HA),具体的实现策略如下所示:

ha-mode ha-params 功能
all 镜像队列将会在整个集群中复制。当一个新的节点加入后,也会在这 个节点上复制一份。
exactly count 镜像队列将会在集群上复制count份。如果集群数量少于count时候,队列会复制到所有节点上。如果大于Count集群,有一个节点crash后,新进入节点也不会做新的镜像。
nodes node name 镜像队列会在node name中复制。如果这个名称不是集群中的一个,这不会触发错误。如果在这个node list中没有一个节点在线,那么这个queue会被声明在client连接的节点。

语法讲解:

# rabbitmqctl set_policy [-p coresystem]  ha-all "^" '{"ha-mode":"all"}'

"coresystem" vhost名称, "^"匹配所有的队列, ha-all 策略名称为ha-all, '{"ha-mode":"all"}' 策略模式为 all 即复制到所有节点,包含新增节点。

则此时镜像队列设置成功。(这里的虚拟主机coresystem是代码中需要用到的虚拟主机,虚拟主机的作用是做一个消息的隔离,本质上可认为是一个rabbitmq-server,是否增加虚拟主机,增加几个,这是由开发中的业务决定,即有哪几类服务,哪些服务用哪一个虚拟主机,这是一个规划)。

可以用查看使用的群集模式

# rabbitmqctl list_policies

(二) RabbitMQ Cluster 配置

1 单机多节点部署

在启动RabbitMQ节点之后,服务器默认的节点名称是Rabbit和监听端口5672,如果想在同一台机器上启动多个节点,那么其他的节点就会因为节点名称和端口与默认的冲突而导致启动失败,可以通过设置环境变量来实现,具体方法如下:

  • 首先在机器上设置两个节点rabbit和rabbit_01

rabbitmqctl stop //先停止运行节点,再进行集群部署
RABBITMQ_NODE_PORT=5672 RABBITMQ_NODENAME=rabbit //设置环境变量指定端口和节点名称
rabbitmq-server -detached //后台启动节点
RABBITMQ_NODE_PORT=5673 RABBITMQ_NODENAME=rabbit_01 //设置环境变量指定端口和节点名称
rabbitmq-server -detached //后台启动节点12345
或者通过添加/etc/rabbitmq/rabbitmq-env.conf文件来进行设置:
NODE_PORT=5672
NODENAME=rabbit
NODE_PORT=5673
NODENAME=rabbit_01
  • 将rabbit_01节点添加到第一个集群节点rabbit中

rabbitmqctl -n rabbit_01@localhost stop_app //停止rabbit_01节点的应用
rabbitmqctl -n rabbit_01@localhost join_cluster rabbit@localhost //将rabbit_01添加到集群节点rabbit中去
rabbitmqctl cluster_status //查看集群节点的状态
rabbitmqctl -n rabbit_01@localhost start_app //启动rabbit_01节点的应用1234
可以看到如下信息,说明节点添加成功,表明都是磁盘类型的节点
Cluster status of node rabbit@localhost ...[{nodes,[{disc,[rabbit@localhost,rabbit_01@localhost]}]},
{running_nodes,[rabbit@localhost]},
{cluster_name,<<"rabbit@localhost">>},
{partitions,[]},
{alarms,[{rabbit@localhost,[]}]}]

2 多机多节点部署

不同于单机多节点的情况,在多机环境,如果要在cluster集群内部署多个节点,需要注意两个方面:

  • 保证需要部署的这几个节点在同一个局域网内

  • 需要有相同的Erlang Cookie,否则不能进行通信,为保证cookie的完全一致,采用从一个节点copy的方式

环境介绍

RabbitMQ节点 IP地址 工作模式 操作系统
node1
10.10.91.57
DISK CentOS 7.2 - 64位
node2
10.10.91.62
DISK CentOS 7.2 - 64位
node3
10.10.91.63
DISK CentOS 7.2 - 64位

cluster部署过程

  • 局域网配置 
    分别在三个节点的/etc/hosts下设置相同的配置信息

10.10.91.57 node1
10.10.91.62 node2
10.10.91.63 node3
  • 设置不同节点间同一认证的Erlang Cookie 
    采用从主节点copy的方式保持Cookie的一致性
    注意:rabbit

[root@node1 ~]# scp /var/lib/rabbitmq/.erlang.cookie 10.10.91.62:/var/lib/rabbitmq
[root@node1 ~]# scp /var/lib/rabbitmq/.erlang.cookie 10.10.91.63:/var/lib/rabbitmq
  • 使用 -detached运行各节点

# rabbitmq-server -detached

# systemctl restart rabbitmq-server.service
  • 查看各节点的状态

#rabbitmqctl cluster_status
  • 创建并部署集群,在node2和node3上执行:

# rabbitmqctl stop_app
# rabbitmqctl reset
# rabbitmqctl join_cluster rabbit@node1
# rabbitmqctl start_app
  • 查看集群状态

# rabbitmqctl cluster_status

更改节点类型(内存型或磁盘型)

# rabbitmqctl stop_app
# rabbitmqctl change_cluster_node_type disc

# rabbitmqctl change_cluster_node_type ram
# rabbitmqctl start_app

也可以通过在配置文件直接写,如下:

[
{rabbit,[{cluster_nodes, {['rabbit@node1', 'rabbit@node2', 'rabbit@node3'], disc|ram}}]}
].

然后直接启用

(三)  RabbitMQ负载均衡配置

前言:从目前来看,基于RabbitMQ的分布式通信框架主要包括两部分内容,一是要确保可用性和性能,另一个就是编写当节点发生故障时知道如何重连到集群的应用程序。负载均衡就是解决处理节点的选择问题。

安装HAProxy

选择开源的HAProxy为RabbitMQ集群做负载均衡器,在CentOS 7.0中安装HAProxy。

  • 安装epel

yum install -y epel-release
  • 安装HAProxy

yum -y install haproxy
  • 配置HAProxy

cp /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.bak
vim /etc/haproxy/haproxy.cfg
  • 添加配置信息

 listen rmq-cluster
  bind 0.0.0.0:5672 
  mode  tcp
  balance  roundrobin
  option  tcplog
  option  tcpka
  server concar-rmq01 10.10.91.57:5672 check
  server concar-rmq02 10.10.91.62:5672 check
  server concar-rmq03 10.10.91.63:5672 check 
  • 访问http://IP:5672就可以看到具体的控制界面。

RabbitMQ分布式集群架构和高可用性(HA)的更多相关文章

  1. 关于RabbitMQ分布式集群架构

    RabbitMQ分布式集群架构和高可用性(HA) (一) 功能和原理 设计集群的目的 允许消费者和生产者在RabbitMQ节点崩溃的情况下继续运行 通过增加更多的节点来扩展消息通信的吞吐量 1 集群配 ...

  2. 【Kubernetes学习之三】Kubernetes分布式集群架构

    环境 centos 7 一.Kubernetes分布式集群架构1.Kubernetes服务注册和服务发现问题怎么解决的?每个服务分配一个不变的虚拟IP+端口, 系统env环境变量里有每个服务的服务名称 ...

  3. 2020重新出发,NOSQL,MongoDB分布式集群架构

    MongoDB分布式集群架构 看到这里相信你已经掌握了 MongoDB 的大部分基本知识,现在在单机环境下操作 MongoDB 已经不存在问题,但是单机环境只适合学习和开发测试,在实际的生产环境中,M ...

  4. Hadoop+Hbase分布式集群架构“完全篇”

    本文收录在Linux运维企业架构实战系列 前言:本篇博客是博主踩过无数坑,反复查阅资料,一步步搭建,操作完成后整理的个人心得,分享给大家~~~ 1.认识Hadoop和Hbase 1.1 hadoop简 ...

  5. 项目十八-Hadoop+Hbase分布式集群架构“完全篇”

    本文收录在Linux运维企业架构实战系列 前言:本篇博客是博主踩过无数坑,反复查阅资料,一步步搭建,操作完成后整理的个人心得,分享给大家~~~ 1.认识Hadoop和Hbase 1.1 hadoop简 ...

  6. 集群(cluster)和高可用性(HA)的概念

    1.1 什么是集群 简单的说,集群(cluster)就是一组计算机,它们作为一个整体向用户提供一组网络资源.这些单个的计算机系统就是集群的节点(node).一个理想的集群是,用户从来不会意识到集群系统 ...

  7. Windows & RabbitMQ:集群(clustering) & 高可用(HA)

    描述:我们需要配置三台服务器:ServerA, ServerB, ServerC 注意事项: 所有的服务器的Erlang版本,RabbitMQ版本必须一样 服务器名大小写敏感 Step 1:安装Rab ...

  8. 基于HBase0.98.13搭建HBase HA分布式集群

    在hadoop2.6.0分布式集群上搭建hbase ha分布式集群.搭建hadoop2.6.0分布式集群,请参考“基于hadoop2.6.0搭建5个节点的分布式集群”.下面我们开始啦 1.规划 1.主 ...

  9. SurFS:共享式和分布式集群各取所长

    http://www.ccidnet.com/2016/0811/10168835.shtml 一个集群系统可以做成三层定义,也就是后端存储访问层.沟通协作层.前端数据访问层,如果愣是要给每个层起个洋 ...

随机推荐

  1. 实现Android Native端爆破源码

    尝试在移动端so侧做一些内存修改,使之走向不通的逻辑,一下为将要爆破的APP源码 JAVA侧: package com.example.grady.sectestone; import android ...

  2. Java工程师成神之路思维导图

    前面看Hollis的微信公众号更新了Java工程师成神之路的文档,感觉里面的内容清晰.齐全,可以用来审视自己,也能够知道自己在那些方面可以继续前行,想着有时间把它画下来,画下来之后分享出来. 主要内容 ...

  3. 点击劫持漏洞之理解 python打造一个挖掘点击劫持漏洞的脚本

    前言: 放假了,上个星期刚刚学习完点击劫持漏洞.没来的及写笔记,今天放学总结了一下 并写了一个检测点击劫持的脚本.点击劫持脚本说一下哈.= =原本是打算把网站源码 中的js也爬出来将一些防御的代码匹配 ...

  4. 查询linux机器的公网ip

    在linux终端提示符下,输入以下命令: curl members.3322.org/dyndns/getip 可以看到下图已经查询到公网IP地址了,就是这么简单

  5. Python基本数据类型之列表、元组、字典、集合及其魔法

    列表 1.列表可存放任何东西,并且可修改 2.列表有序 3.列表支持索引与切片 4.支持for,while循环,所以列表为可迭代对象 5支持in操作,判断元素是否在列表中 6可多重索引嵌套列表 7.字 ...

  6. activeMq的入门程序

    生产者 1.导入相关依赖 2.交给Spring管理,写入相关配置JmsTemplate @RunWith(SpringJUnit4ClassRunner.class) @ContextConfigur ...

  7. Spark学习笔记

    Map-Reduce 我认为上图代表着MapReduce不仅仅包括Map和Reduce两个步骤这么简单,还有两个隐含步骤没有明确,全部步骤包括:切片.转换.聚合.叠加,按照实际的运算场景上述步骤可以简 ...

  8. 托管C++线程锁实现

    最近由于工作需要,开始写托管C++,由于C++11中的mutex,和future等类,托管C++不让调用(报错),所以自己实现了托管C++的线程锁. 该类可确保当一个线程位于代码的临界区时,另一个线程 ...

  9. python笔记:#004#注释

    注释 目标 注释的作用 单行注释(行注释) 多行注释(块注释) 01. 注释的作用 使用用自己熟悉的语言,在程序中对某些代码进行标注说明,增强程序的可读性 02. 单行注释(行注释) 以 # 开头,# ...

  10. Java 核心卷学习笔记(一)

    Java基程序设计结构 1.注释 三种注释方式: // 注释单行 /* 内容 */ 注释单行 /** * 内容 */