RabbitMQ集群-镜像模式搭建

[TOC]

简介

RabbitMQ是基于Erlang编写,Erlang语言天生具备分布式个性(通过同步Erlang集群各节点的magic cookie来实现)。因而,RabbitMQ人造反对Clustering。这使得RabbitMQ自身不须要像ActiveMQ、Kafka那样通过ZooKeeper别离来实现HA高可用计划和保留集群的元数据。集群是保障可靠性的一种形式,同时能够通过程度扩大以达到减少音讯吞吐量能力的目标。

单机模式

个别就是本地启动进行开发,不用于生产用

高可用模式

主备模式

Warren 模式。实现 rabbitMQ 的高可用集群,个别在并发和数据量不高的状况下,这种模式十分的好用且简略。 也就是一个主/备计划,主节点提供读写,备用节点不提供读写。如果主节点挂了,就切换到备用节点,原来的备用节点降级为主节点提供读写服务,当原来的主节点复原运行后,原来的主节点就变成备用节点,和 activeMQ 利用 zookeeper 做主/备一样,也能够一主多备。

<img src="https://test-1251230131.cos.ap-shanghai.myqcloud.com//imgimage-20201206161314300.png" style="zoom:50%;" />

近程模式

近程模式能够实现双活的一种模式,简称 shovel 模式,所谓的 shovel 就是把音讯进行不同数据中心的复制工作,能够跨地区的让两个 MQ 集群互联,远距离通信和复制。 Shovel 就是咱们能够把音讯进行数据中心的复制工作,咱们能够跨地区的让两个 MQ 集群互联。rabbitMQ 比拟晚期的架构模型了,当初很少应用了。

多活模式

多活模式:这种模式也是实现异地数据复制的支流模式,因为Shovel模式配置比较复杂,所以一般来说实现异地集群都是应用这种双活或者多活模型来实现的。这种模型须要依赖rabbitmq的federation插件,能够实现继续的牢靠的AMQP数据通信,多活模式在理论配置与利用上十分的简略。提供了更牢靠的齐备的数据保障,即便一个集群挂掉,也还有另外一个集群。

RabbitMQ部署架构采纳双核心模式(多核心) , 那么在两套(或多套)数据中心中各部署一套RabbitMQ集群,各核心的RabbitMQ服务除了须要为业务提供失常的音讯服务外,核心之间还须要实现局部队列音讯共享。

集群模式

一般集群

默认模式,RabbitMQ集群中节点包含内存节点、磁盘节点。内存节点就是将所有数据放在内存,磁盘节点将数据放在磁盘上。如果在投递音讯时,关上了音讯的长久化,那么即便是内存节点,数据还是平安的放在磁盘。那么内存节点的性能只能体现在资源管理上,比方减少或删除队列(queue),虚拟主机(vrtual hosts),交换机(exchange)等,发送和承受message速度同磁盘节点一样。一个集群至多要有一个磁盘节点。一个rabbitmq集群中能够共享user,vhost,exchange等,所有的数据和状态都是必须在所有节点上复制的,对于queue依据集群模式不同,应该有不同的体现。在集群模式下只有有任何一个节点可能工作,RabbitMQ集群对外就能提供服务。

以两个节点(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 节点复原,而后才可被生产;如果没有长久化的话,就会产生音讯失落的景象。

<img src="https://test-1251230131.cos.ap-shanghai.myqcloud.com//imgimage-20201206162559999.png" style="zoom:50%;" />

镜像集群

十分经典的 mirror 镜像模式,保障 100% 数据不失落。在理论工作中也是用得最多的,并且实现十分的简略,个别互联网大厂都会构建这种镜像集群模式。

把须要的队列做成镜像队列,存在与多个节点属于 RabbitMQ 的 HA 计划。该模式解决了一般模式中的问题,其实质和一般模式不同之处在于,音讯实体会被动在镜像节点间同步,而不是在客户端取数据时长期拉取。该模式带来的副作用也很显著,除了升高零碎性能外,如果镜像队列数量过多,加之大量的音讯进入,集群外部的网络带宽将会被这种同步通信大大消耗掉。所以在对可靠性要求较高的场合中实用。

镜像队列基本上就是一个非凡的BackingQueue,它外部包裹了一个一般的BackingQueue做本地音讯长久化解决,在此基础上减少了将音讯和ack复制到所有镜像的性能。所有对mirror_queue_master的操作,会通过组播GM(上面会讲到)的形式同步到各slave节点。GM负责音讯的播送,mirror_queue_slave负责回调解决,而master上的回调解决是由coordinator负责实现。mirror_queue_slave中蕴含了一般的BackingQueue进行音讯的存储,master节点中BackingQueue蕴含在mirror_queue_master中由AMQQueue进行调用。

环境筹备

软件介质

软件版本备注
rabbitmq3.8.8须要装置对应的erlang版本
erlang23.xrabbitmq对应erlang版本

主机资源

主机名操作系统IP备注
rabbitmq1centos7.4192.168.1.1磁盘节点,治理节点
rabbitmq2centos7.4192.168.1.2内存节点
rabbitmq3centos7.4192.168.1.3内存节点

hosts设置

批改/etc/hosts文件

192.168.1.1 rabbitmq1192.168.1.2 rabbitmq2192.168.1.3 rabbitmq3

根底搭建

别离在以上三台主机上执行如下步骤:

1. erlang装置

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

验证

[root@rabbitmq1 ~]# erlErlang/OTP 23 [erts-11.1] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [hipe]Eshell V11.1  (abort with ^G)

2. rabbitmq装置

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

验证

[root@rabbitmq1 ~]$ systemctl status rabbitmq-server.service● rabbitmq-server.service - RabbitMQ broker   Loaded: loaded (/usr/lib/systemd/system/rabbitmq-server.service; enabled; vendor preset: disabled)   Active: active (running) since Sat 2020-12-05 15:34:50 UTC; 13h ago Main PID: 11663 (beam.smp)   Status: "Initialized"   CGroup: /system.slice/rabbitmq-server.service           ├─11663 /usr/lib64/erlang/erts-11.1/bin/beam.smp -W w -K true -A 128 -MBas ageffcbf -MHas ageffcbf -MBlmbcs 512 -MHlmbcs 512 -MMmcs 30 -P 1048576 -t 5000000 -stbt db -zdbbl 128000 -- -root ...           ├─11844 erl_child_setup 32768           ├─11918 inet_gethost 4           └─11919 inet_gethost 4

创立集群

将rabbitmq1作为群集的治理节点。

1.配置集群根底环境

copy erlang集群文件到rabbitmq2、rabbitmq3的/var/lib/rabbitmq/目录中,将重启systemctl restart rabbitmq-server rabbitmq2、rabbitmq3的服务。

# 查看erlang分布式集群文件[root@rabbitmq1 ~]# ls -al /var/lib/rabbitmqtotal 8drwxr-xr-x   3 rabbitmq rabbitmq   42 Oct 30 21:47 .drwxr-xr-x. 27 root     root     4096 Oct 30 21:20 ..-r--------   1 rabbitmq rabbitmq   20 Oct 30 00:00 .erlang.cookiedrwxr-x---   4 rabbitmq rabbitmq  135 Oct 30 21:47 mnesia# 查看.erlang.cookie内容[root@rabbitmq1 rabbitmq]# cat .erlang.cookie SFWVLUCDUUVPIVRJDWTE[root@rabbitmq1 rabbitmq]## copy .erlang.cookie 文件到其它主机对应的目录中[root@rabbitmq1 rabbitmq]# scp .erlang.cookie  root@rabbitmq2:/var/lib/rabbitmq/root@rabbitmq2's password: .erlang.cookie                             100%   20    27.0KB/s   00:00    [root@rabbitmq1 rabbitmq]# scp .erlang.cookie  root@rabbitmq3:/var/lib/rabbitmq/root@rabbitmq3's password: .erlang.cookie                             100%   20    36.7KB/s   00:00s

2.将节点退出集群中

将rabbitmq2、rabbitmq3退出群集

# 在rabbitmq1上看群集的状态[root@rabbitmq1 ~]# rabbitmqctl cluster_statusCluster status of node rabbit@rabbitmq1 ...BasicsCluster name: rabbit@rabbitmq1Disk Nodesrabbit@rabbitmq1Running Nodesrabbit@rabbitmq1Versionsrabbit@rabbitmq1: RabbitMQ 3.8.8 on Erlang 23.1Maintenance statusNode: rabbit@rabbitmq1, status: not under maintenanceAlarms(none)Network Partitions(none)ListenersNode: rabbit@rabbitmq1, interface: [::], port: 25672, protocol: clustering, purpose: inter-node and CLI tool communicationNode: rabbit@rabbitmq1, interface: [::], port: 5672, protocol: amqp, purpose: AMQP 0-9-1 and AMQP 1.0Node: rabbit@rabbitmq1, interface: [::], port: 15672, protocol: http, purpose: HTTP APIFeature flagsFlag: drop_unroutable_metric, state: disabledFlag: empty_basic_get_metric, state: disabledFlag: implicit_default_bindings, state: enabledFlag: maintenance_mode_status, state: enabledFlag: quorum_queue, state: enabledFlag: virtual_host_metadata, state: enabled# 在rabbitmq2操作退出群集# 1.进行rabbitmq2上的服务[root@rabbitmq2 ~]# rabbitmqctl stop_appStopping rabbit application on node rabbit@rabbitmq2 ...# 2.进行rabbitmq2上的服务[root@rabbitmq2 ~]# rabbitmqctl resetResetting node rabbit@rabbitmq2 ...# 2.将rabbitmq2退出集群,--ram是以内存形式退出[root@rabbitmq2 ~]# rabbitmqctl join_cluster --ram rabbit@rabbitmq1Clustering node rabbit@rabbitmq2 with rabbit@rabbitmq1# 3.启动rabbitmq2上的服务[root@rabbitmq2 ~]# rabbitmqctl  start_appStarting node rabbit@rabbitmq2 ...# rabbitmq3以同样的形式退出即可

验证:

# 查看群集状态[root@rabbitmq1 ~]# rabbitmqctl cluster_statusCluster status of node rabbit@rabbitmq1 ...BasicsCluster name: rabbit@rabbitmq1Disk Nodesrabbit@rabbitmq1RAM Nodesrabbit@rabbitmq2rabbit@rabbitmq3Running Nodesrabbit@rabbitmq1rabbit@rabbitmq2rabbit@rabbitmq3Versionsrabbit@rabbitmq1: RabbitMQ 3.8.9 on Erlang 21.3.8.18rabbit@rabbitmq2: RabbitMQ 3.8.9 on Erlang 21.3.8.18rabbit@rabbitmq3: RabbitMQ 3.8.9 on Erlang 21.3.8.18Maintenance statusNode: rabbit@rabbitmq1, status: not under maintenanceNode: rabbit@rabbitmq2, status: not under maintenanceNode: rabbit@rabbitmq3, status: not under maintenanceAlarms(none)Network Partitions(none)ListenersNode: rabbit@rabbitmq1, interface: [::], port: 25672, protocol: clustering, purpose: inter-node and CLI tool communicationNode: rabbit@rabbitmq1, interface: [::], port: 5672, protocol: amqp, purpose: AMQP 0-9-1 and AMQP 1.0Node: rabbit@rabbitmq1, interface: [::], port: 15672, protocol: http, purpose: HTTP APINode: rabbit@rabbitmq2, interface: [::], port: 15672, protocol: http, purpose: HTTP APINode: rabbit@rabbitmq2, interface: [::], port: 25672, protocol: clustering, purpose: inter-node and CLI tool communicationNode: rabbit@rabbitmq2, interface: [::], port: 5672, protocol: amqp, purpose: AMQP 0-9-1 and AMQP 1.0Node: rabbit@rabbitmq3, interface: [::], port: 15672, protocol: http, purpose: HTTP APINode: rabbit@rabbitmq3, interface: [::], port: 25672, protocol: clustering, purpose: inter-node and CLI tool communicationNode: rabbit@rabbitmq3, interface: [::], port: 5672, protocol: amqp, purpose: AMQP 0-9-1 and AMQP 1.0

3.将集群设为镜像模式

在咱们应用 rabbitmq 作为音讯服务时,在服务负载不是很大的状况下,个别咱们只须要一个 rabbitmq 节点便能为咱们提供服务,可这难免会产生单点故障,要解决这个问题,咱们便须要配置 rabbitmq 的集群和镜像。

镜像模式参数
rabbitmqctl set_policy [-p Vhost] Name Pattern Definition [Priority] -p Vhost:  可选参数,针对指定vhost下的queue进行设置Name:       policy的名称Pattern:    exchanges或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和manual。automatic:新减少节点主动同步全量数据。manual: 新增节点只同步新增数据,全量数据须要手工同步。Priority:可选参数,policy的优先级
设置示例
# 所有队列exchangess 或者 queue都为镜像模式[root@rabbitmq1 ~]# 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@rabbitmq1 ~]# rabbitmqctl set_policy --priority 0 --apply-to queues mirror_queue "^queue_" '{"ha-mode":"exactly","ha-params":2,"ha-sync-mode":"automatic"}'