RabbitMQ 集群部署

小丫1年前技术文章462

1. 两种模式

说到集群,小伙伴们可能第一个问题是,如果我有一个 RabbitMQ 集群,那么是不是我的消息集群中的每一个实例都保存一份呢?

这其实就涉及到 RabbitMQ 集群的两种模式:

1)普通集群

2)镜像集群

1.1 普通集群

普通集群模式,就是将 RabbitMQ 部署到多台服务器上,每个服务器启动一个 RabbitMQ 实例,多个实例之间进行消息通信。

此时我们创建的队列 Queue,它的元数据(主要就是 Queue 的一些配置信息)会在所有的 RabbitMQ 实例中进行同步,但是队列中的消息只会存在于一个 RabbitMQ 实例上,而不会同步到其他队列。

当我们消费消息的时候,如果连接到了另外一个实例,那么那个实例会通过元数据定位到 Queue 所在的位置,然后访问 Queue 所在的实例,拉取数据过来发送给消费者。

这种集群可以提高 RabbitMQ 的消息吞吐能力,但是无法保证高可用,因为一旦一个 RabbitMQ 实例挂了,消息就没法访问了,如果消息队列做了持久化,那么等 RabbitMQ 实例恢复后,就可以继续访问了;如果消息队列没做持久化,那么消息就丢了。

大致的流程图如下图:

image.png

1.2 镜像集群

它和普通集群最大的区别在于 Queue 数据和原数据不再是单独存储在一台机器上,而是同时存储在多台机器上。也就是说每个 RabbitMQ 实例都有一份镜像数据(副本数据)。每次写入消息的时候都会自动把数据同步到多台实例上去,这样一旦其中一台机器发生故障,其他机器还有一份副本数据可以继续提供服务,也就实现了高可用。

大致流程图如下图:

image.png

1.3 节点类型

RabbitMQ 中的节点类型有两种:

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

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

RabbitMQ 要求在集群中至少有一个磁盘节点,所有其他节点可以是内存节点,当节点加入或者离开集群时,必须要将该变更通知到至少一个磁盘节点。如果集群中唯一的一个磁盘节点崩溃的话,集群仍然可以保持运行,但是无法进行其他操作(增删改查),直到节点恢复。为了确保集群信息的可靠性,或者在不确定使用磁盘节点还是内存节点的时候,建议直接用磁盘节点。

2. 搭建基础集群

2.1 环境准备

系统系统:CentOS7 64位

三台服务器:10.90.0.9/10/11

服务器规划

服务器用途主机名节点类型

10.90.0.11

RabbitMQ 集群节点 1

dev-big-data01

磁盘节点

10.90.0.9

RabbitMQ 集群节点 2

dev-big-data02

磁盘节点

10.90.0.10

RabbitMQ 集群节点 3

dev-big-data03

磁盘节点

2.2 erlang 安装

# 下载erlang软件包源
wget https://packages.erlang-solutions.com/erlang-solutions-1.0-1.noarch.rpm
sudo yum install epel-release -y
# 安装erlang软件包源
sudo rpm -Uvh erlang-solutions-1.0-1.noarch.rpm
# 安装erlang环境
sudo yum install erlang -y

验证:

 image.png

2.3 rabbitmq 安装

# 下载介质源
wget https://github.com/rabbitmq/rabbitmq-server/releases/download/v3.9.16/rabbitmq-server-3.9.16-1.el7.noarch.rpm
# 安装介质源
yum install -y rabbitmq-server-3.9.16-1.el7.noarch.rpm
# 打开开启动
systemctl enable rabbitmq-server
# 启动服务
systemctl start rabbitmq-server
# 查看服务状态
systemctl status rabbitmq-server

验证:

image.png

3. 创建集群

3.1 配置 erlang cookie

RabbitMQ 集群是基于 erlang 进行同步的,在 erlang 的集群中各节点同步需要一个相同的 cookie,所以必须保证各节点 cookie 一致,不然节点之间就无法通信,,这个 cookie 默认存放在 /var/lib/rabbitmq/.erlang.cookie 中。

在任意一个节点中 copy .erlang.cookie 文件到其它所有节点,如在 node1 上进行 copy :

image.png

注意:
     各节点都必须停止MQ服务

     拷贝过去之后权限要进行修改,否则rabbitmq服务会无法启动

     chown rabbitmq:rabbitmq /var/lib/rabbitmq/.erlang.cookie        //属主,属组

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

重启所有服务

systemctl restart  rabbitmq-server

3.2  将节点加入到集群中

node2、node3  节点加入 node1 节点集群中, node2、node3中分别执行以下命令:

# rabbitmqctl stop_app
# rabbitmqctl join_cluster rabbit@node1
# rabbitmqctl start_app

默认 RabbitMQ 启动后是磁盘节点,在这个 cluster 下,node1、node2 和 node3 都是是磁盘节点。

如果要使 node2、node3 都是内存节点,加上 --ram 参数即可,如 rabbitmqctl join_cluster --ram rabbit@node1

如果想要更改节点类型,可以使用命令 rabbitmqctl change_cluster_node_type disc(ram),修改节点类型前需要先 rabbitmqctl stop_app

(Note: disk and disc are used interchangeably)

验证是否加入:

image.png

3.3  将集群设为镜像模式

镜像模式参数

rabbitmqctl set_policy [-p Vhost] Name Pattern Definition [Priority]

 

-p Vhost:  可选参数,针对指定vhost下的queue进行设置

Name:       policy的名称

Pattern:    exchangesqueue的匹配模式(正则表达式)

Definition:镜像定义,包括三个部分ha-mode, ha-params, ha-sync-mode

    ha-mode:指明镜像队列的模式,有效值为 all/exactly/nodes

        all:表示在集群中所有的节点上进行镜像

        exactly:表示在指定个数的节点上进行镜像,节点的个数由ha-params指定

        nodes:表示在指定的节点上进行镜像,节点名称通过ha-params指定

    ha-paramsha-mode模式需要用到的参数

    ha-sync-mode:进行队列中消息的同步方式,有效值为automaticmanualautomatic:新增加节点自动同步全量数据。manual: 新增节点只同步新增数据,全量数据需要手工同步。

Priority:可选参数,policy的优先级
设置实例

# 所有队列exchangess 或者 queue都为镜像模式

[root@rabbitmq-01 ~]# rabbitmqctl set_policy ha-all "^" '{"ha-mode":"all"}'

Setting policy "ha-all" for pattern "^" to "{"ha-mode":"all"}" with priority "0" for vhost "/" ...

 

# 对队列名称以“queue_”开头的所有队列进行镜像,并在集群的两个节点上完成进行,policy的设置命令为:

[root@rabbitmq-01 ~]# rabbitmqctl set_policy --priority 0 --apply-to queues mirror_queue "^queue_" '{"ha-mode":"exactly","ha-params":2,"ha-sync-mode":"automatic"}'

3.3  集群验证

3.3.1 开启插件

所有机器执行命令: rabbitmq-plugins enable rabbitmq_management
设置账户:
rabbitmqctl add_user admin 密码 // 添加用户名
rabbitmqctl set_user_tags admin administrator // 提升管理员
rabbitmqctl set_permissions -p / admin ".*" ".*" ".*" // 为 admin 用户配置所有权限
在浏览器中访问 http://10.90.0.11:15672

image.png

3.3.2镜像集群验证

上面我们已经设置过策略,全部队列都做镜像模式,这里我们创建一个队列

image.png

可以看到我们创建了queue_testQueue队列,Node中的+2表示备份,下图中的Mirrors就是备份的节点,若node3宕机了node1,node2就会代替node3继续提供服务

image.png

测试:首先关闭node3 节点

image.png

   然后查看node1,node2 节点上的镜像状态,发现在node1,node2 节点也进行了备份,以此说明:就算整个集群只剩下一台机器了,依然能消费队列里面的消息

image.png

 

 

 

 

4 负载均衡

4.1 安装haproxy

   yum install haproxy -y 

4.2  配置haproxy

vim /etc/haproxy/haproxy.cfg 编辑 haproxy 配置文件,修改如下

image.png

 

4.3  运行haproxy

systemctl restart haproxy    //运行 haproxy 

 

systemctl status haproxy      //查看状态

浏览器访问 http://10.90.0.9:8888/stats,输入配置中的用户名和密码登录

image.png

5 集群启动和关闭

5.1 停止集群

 集群是不能通过一个命令完全停止的,它必须对各个节点依次停止才能最终停止集群,而且基准节点要作为最后一个停止,先停止其它加入到基准节点的节点.

例如,我们上述将node2机器和node3机器的节点加入到node1机器的基准节点,那么停止时需要先停止node2机器和node3机器的节点,最后再停止node1机器节点(注:集群启动时就与此顺序相反,先启动node1机器的节点,再启动node2和node3的节点),按照顺序执行如下:
./rabbitmqctl stop
按照node3、node2、node1的顺序执行此条命令即可停止整个集群。

5.2 重启/重置节点

重启某一个节点执行步骤如下:

./rabbitmqctl stop

./rabbitmq-server -detached

注:重启节点实际上就是先执行停止,再启动即可,不需要再次加入到集群节点中,启动之后节点自动会加入到集群中(初次加入集群就需要加入某一个节点)。重置某一个节点,就是先停止该节点,然后执行reset命令清除所有数据,接着加入到集群中并启动,如下/rabbitmqctl stop_app

./rabbitmqctl reset

./rabbitmqctl join_cluster rabbit@NodeName

./rabbitmqctl start_app

注:重启过程中,节点停止后主节点同步过来的数据将无法保存在此节点,同理重置过程中,节点停止后也将无法获取同步的数据,reset重置还会将此节点原来所有的数据(队列、交换器、虚拟机、用户和同步过来的消息等)全部清除,直到重新加入集群、重启节点后可再次同步数据。

5.3 创建内存节点

前面说到内存节点和磁盘节点的区别,当我们把一个节点加入到集群中时,默认是以磁盘节点加入集群的,如果要以内存节点加入集群,只需要在加入集群时带上–ram参数就行了,如下:

./rabbitmqctl join_cluster --ram rabbit@NodeName1

5.4 改变节点类型

通过改变节点类型可以将磁盘节点改为内存节点,也可以将内存节点改为磁盘节点,如下:

./rabbitmqctl stop_app

./rabbitmqctl change_cluster_node_type disc

# disc是磁盘节点,ram是内存节点

./rabbitmqctl start_app


相关文章

Elasticsearch写入优化

1.1 基本优化手段Elasticsearch默认的设置和参数配置下,是综合考虑了数据的可靠性、搜索实时性、写入速度等因素。但在安平实际场景中,业务对数据的可靠性和搜索实时性要求并不高,反而对写入速度...

副本集的同步、心跳、选举、回滚

一、副本集同步过程   MongoDB的复制功能是依赖与oplog来实现的。   1.数据写入主节点同时在local.oplog.rs集合写入对应的oplog   2.备份节点第一次同步数据时,会先进...

Helm 控制语句

Helm 控制结构(在模板语言中称为 "actions")提供给你和模板作者控制模板迭代流的能力。 Helm 的模板语言提供了以下控制结构:if/else,用来创建条件语句with,用来指定范围ran...

MySQL运维实战(2)MySQL用户和权限管理

MySQL用户管理基本命令创建用户使用create user命令创建用户create user 'username'@'host' ide...

scylladb集群如何添加新数据中心

1、信息收集· 收集现有集群信息cat /etc/scylla/scylla.yaml | grep cluster_namecat /etc/scylla/scylla.yaml | grep se...

doris-manager部署doris

doris-manager部署doris

1.下载Doris安装包登陆地址https://doris.apache.org/download选择需要下载的版本,这里选择2.0.2 source版本2.部署cluster manager(1)下...

发表评论    

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。