官网英文版学习——RabbitMQ学习笔记(十)RabbitMQ集群

时间:2023-12-16 12:04:44

在第二节我们进行了RabbitMQ的安装,现在我们就RabbitMQ进行集群的搭建进行学习,参考官网地址是:http://www.rabbitmq.com/clustering.html

首先我们来看一下官网对集群的定义:A RabbitMQ broker is a logical grouping of one or several Erlang nodes, each running the RabbitMQ application and sharing users, virtual hosts, queues, exchanges, bindings, and runtime parameters. Sometimes we refer to the collection of nodes as a cluster.

简单翻译一下是说:RabbitMQ的broker是一个或多个Erlang节点的逻辑分组,每个节点运行RabbitMQ应用程序并共享用户、虚拟主机、队列、交换、绑定和运行时参数。有时,我们将节点集合称为集群。

集群将多个机器连接在一起,形成一个单一的逻辑代理。通信是通过Erlang消息传递进行的,因此集群中的所有节点都必须具有相同的Erlang cookie。集群中的机器之间的网络连接必须是可靠的,集群中的所有机器都必须运行相同版本的RabbitMQ和Erlang。

虚拟主机、交换器、用户和权限在集群中的所有节点上被自动镜像。队列可以位于单个节点上,也可以跨多个节点镜像。连接到集群中任何节点的客户端可以看到集群中的所有队列,即使它们不在该节点上。

通常,您将使用集群实现高可用性和提高吞吐量,并将机器放在一个位置。

集群方式:

RabbitMQ集群可以通过多种方式形成:

  • 通过在配置文件中以声明的方式列出集群节点
  • 声明性地使用以域名系统发现
  • 以声明的方式使用AWS (EC2)实例发现(通过插件)
  • 使用Kubernetes发现(通过插件)声明
  • 声明性地使用基于咨询的发现(通过插件)
  • 以声明的方式使用基于etcd的发现(通过插件)

集群的组成可以动态地改变。所有RabbitMQ代理都以在单个节点上运行开始。这些节点可以被连接到集群中,然后再返回到各个代理中。

集群模式(两种):

1)普通模式(默认模式):

RabbitMQ集群中节点包括内存节点、磁盘节点。内存节点就是将所有数据放在内存,磁盘节点将数据放在磁盘上。如果在投递消息时,打开了消息的持久化,那么即使是内存节点,数据还是安全的放在磁盘。那么内存节点的性能只能体现在资源管理上,比如增加或删除队列(queue),虚拟主机(vrtual hosts),交换机(exchange)等,发送和接受message速度同磁盘节点一样。一个集群至少要有一个磁盘节点。一个rabbitmq集群中可以共享user,vhost,exchange等,所有的数据和状态都是必须在所有节点上复制的,对于queue根据集群模式不同,应该有不同的表现。在集群模式下只要有任何一个节点能够工作,RabbitMQ集群对外就能提供服务。

默认的集群模式,queue创建之后,如果没有其它policy,则queue就会按照普通模式集群。对于Queue来说,消息实体只存在于其中一个节点,A、B两个节点仅有相同的元数据,即队列结构,但队列的元数据仅保存有一份,即创建该队列的rabbitmq节点(A节点),当A节点宕机,你可以去其B节点查看,./rabbitmqctl list_queues发现该队列已经丢失,但声明的exchange还存在。

当消息进入A节点的Queue中后,consumer从B节点拉取时,RabbitMQ会临时在A、B间进行消息传输,把A中的消息实体取出并经过B发送给consumer,所以consumer应平均连接每一个节点,从中取消息。该模式存在一个问题就是当A节点故障后,B节点无法取到A节点中还未消费的消息实体。如果做了队列持久化或消息持久化,那么得等A节点恢复,然后才可被消费,并且在A节点恢复之前其它节点不能再创建A节点已经创建过的持久队列;如果没有持久化的话,消息就会失丢。这种模式更适合非持久化队列,只有该队列是非持久的,客户端才能重新连接到集群里的其他节点,并重新创建队列。假如该队列是持久化的,那么唯一办法是将故障节点恢复起来。

为什么RabbitMQ不将队列复制到集群里每个节点呢?这与它的集群的设计本意相冲突,集群的设计目的就是增加更多节点时,能线性的增加性能(CPU、内存)和容量(内存、磁盘)。当然RabbitMQ新版本集群也支持队列复制(有个选项可以配置)。比如在有五个节点的集群里,可以指定某个队列的内容在2个节点上进行存储,从而在性能与高可用性之间取得一个平衡(应该就是指镜像模式)。

2)镜像模式:

该模式解决了上述问题,其实质和普通模式不同之处在于,消息实体会主动在镜像节点间同步,而不是在consumer取数据时临时拉取。该模式带来的副作用也很明显,除了降低系统性能外,如果镜像队列数量过多,加之大量的消息进入,集群内部的网络带宽将会被这种同步通讯大大消耗掉。所以在对可靠性要求较高的场合中适用,一个队列想做成镜像队列,需要先设置policy,然后客户端创建队列的时候,rabbitmq集群根据“队列名称”自动设置是普通集群模式或镜像队列。

下面开始两种模式的集群,我们的集群环境仍然是之前一直采用的几个虚拟机中进行

在linux下centos6.7上进行,

一、在三台虚拟机上分别安装rabbitMQ

安装可以参考本人前面的教程

这里我们对上面链接中安装内容做个简化,整理如下:

1.添加存储库条目

wget https://packages.erlang-solutions.com/erlang-solutions-1.0-1.noarch.rpm
rpm -Uvh erlang-solutions-1.0-1.noarch.rpm

官网英文版学习——RabbitMQ学习笔记(十)RabbitMQ集群

官网英文版学习——RabbitMQ学习笔记(十)RabbitMQ集群

2.安装erlang,安装完成如下(安装有些慢需要些时间大约6~10min):

sudo yum install erlang

官网英文版学习——RabbitMQ学习笔记(十)RabbitMQ集群

3.安装centos的epel的扩展源

yum -y install epel-release

官网英文版学习——RabbitMQ学习笔记(十)RabbitMQ集群

4.之后执行yum -y install socat重新 安装socat

官网英文版学习——RabbitMQ学习笔记(十)RabbitMQ集群

5.安装rabbitmq

rpm --import https://dl.bintray.com/rabbitmq/Keys/rabbitmq-release-signing-key.asc
# this example assumes the CentOS 7 version of the package
yum install rabbitmq-server-3.7.6-1.el7.noarch.rpm

官网安装的是3.7.6-1.e17如上图,结合本centos是32位字节,下载3.7.6-1.e16,并上传到usr/local/目录下,安装运行

yum install rabbitmq-server-3.7.6-1.e16.noarch.rpm成功。

官网英文版学习——RabbitMQ学习笔记(十)RabbitMQ集群

6、启动RabbitMQ测试

官网英文版学习——RabbitMQ学习笔记(十)RabbitMQ集群

显示启动成功,OK!

附上网上查找的有关rabbitMQ命令

service rabbitmq-server start    启动

service rabbitmq-server stop    停止

service rabbitmq-server restart   重启

二、

在上述的三台机器上安装rabbitmq完成之后,你可以看到你的机器中有如下1个文件。路径在$HOME中或者在/var/lib/rabbitmq中,文件名称为.erlang.cookie,他是一个隐藏文件。

官网英文版学习——RabbitMQ学习笔记(十)RabbitMQ集群

那么这文件存储的内容是什么,是做什么用的呢?

该文件是集群节点进行通信的验证密钥,所有节点必须一致。RabbitMQ的集群是依赖erlang集群,而erlang集群是通过这个cookie进行通信认证的,拷完后重启下RabbitMQ。因此我们做集群的第一步就是干cookie。怎么干?

1、必须使集群中也就是上面三台机器中的这两台机器的.erlang.cookie文件中cookie值一致,且权限为owner只读。

三台机子三个文件内容分别是

官网英文版学习——RabbitMQ学习笔记(十)RabbitMQ集群

官网英文版学习——RabbitMQ学习笔记(十)RabbitMQ集群

官网英文版学习——RabbitMQ学习笔记(十)RabbitMQ集群

修改三台机子文件中的内容完全一样即可,不管采用那台机子上的均可,这里本博主采用第一个文件TUWHXTFBJHBQTONCAXCA

修改文件权限 chmod 600 /var/lib/.erlang.cookie

进入安装的sbin下查看目录,不知道sbin安装目录可以输入命令whereis rabbitmq-server查找

官网英文版学习——RabbitMQ学习笔记(十)RabbitMQ集群

cd /usr/sbin/后查看状态

官网英文版学习——RabbitMQ学习笔记(十)RabbitMQ集群

此时直接去查看其他两个节点状态发现报错,第二天早上开机后竟然好了,肯能是重启的缘故,先上图其他两台的状态

官网英文版学习——RabbitMQ学习笔记(十)RabbitMQ集群

官网英文版学习——RabbitMQ学习笔记(十)RabbitMQ集群

从上面可以看到,本博主前两台主机名是一样的,这是由于本博主之前搭建虚拟机时采用的复制虚拟机,导致虚拟机主机名一致,为了进行rabbitMQ集群,我们需要对三台主机设置主机名并进行绑定,本博主决定分别设置其主机名为rabbitA,rabbitB和rabbitC,并且一定要确保集群中每台节点机器上的hosts文件应包含集群内所有节点的信息以保证互相解析。在未进行配置的情况下,当我们在加入节点到另一个节点时报错如下:

官网英文版学习——RabbitMQ学习笔记(十)RabbitMQ集群

接下来我们进行每台主机的hosts配置:

官网英文版学习——RabbitMQ学习笔记(十)RabbitMQ集群

官网英文版学习——RabbitMQ学习笔记(十)RabbitMQ集群

官网英文版学习——RabbitMQ学习笔记(十)RabbitMQ集群

注意也要同时修改

官网英文版学习——RabbitMQ学习笔记(十)RabbitMQ集群

然后重启生效如下,主机名变为rabbitA,:

官网英文版学习——RabbitMQ学习笔记(十)RabbitMQ集群

设置完成,我们相互ping一下,看是否可以相互连接

官网英文版学习——RabbitMQ学习笔记(十)RabbitMQ集群

我们再次加入节点时,仍然报错如下:

官网英文版学习——RabbitMQ学习笔记(十)RabbitMQ集群

到此,根据网上各种情况排查发现都不行,什么情况呢,主机名,cookie值,防火墙都排出了,就剩安装顺序了,莫非真的必须先更改主机名,再安装rabbitmq才行吗。各位大神,知道的留个言