阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

RabbitMQ两种集群模式配置管理

162次阅读
没有评论

共计 8788 个字符,预计需要花费 22 分钟才能阅读完成。

RabbitMQ 集群的两种模式
1)普通模式:默认的集群模式。

2)镜像模式:把需要的队列做成镜像队列。

普通模式:默认的集群模式

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 个节点上进行存储,从而在性能与高可用性之间取得一个平衡(应该就是指镜像模式)。

镜像模式:把需要的队列做成镜像队列,存在于多个节点,属于 RabbitMQ 的 HA 方案

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

队列通过策略来使能镜像。策略能在任何时刻改变,rabbitmq 队列也近可能的将队列随着策略变化而变化;非镜像队列和镜像队列之间是有区别的,前者缺乏额外的镜像基础设施,没有任何 slave,因此会运行得更快。

为了使队列称为镜像队列,你将会创建一个策略来匹配队列,设置策略有两个键“ha-mode 和 ha-params(可选)”。ha-params 根据 ha-mode 设置不同的值,下面表格说明这些 key 的选项。

RabbitMQ 两种集群模式配置管理

语法讲解:

在 cluster 中任意节点启用策略,策略会自动同步到集群节点

1 rabbitmqctl set_policy-p/ha-all”^”‘{“ha-mode”:”all”}’

这行命令在 vhost 名称为 hrsystem 创建了一个策略,策略名称为 ha-allqueue, 策略模式为 all 即复制到所有节点,包含新增节点,策略正则表达式为“^”表示所有匹配所有队列名称。例如:

1 rabbitmqctl set_policy-p/ha-all”^message”‘{“ha-mode”:”all”}’

注意:“^message”这个规则要根据自己修改,这个是指同步“message”开头的队列名称,我们配置时使用的应用于所有队列,所以表达式为“^”

RabbitMQ 普通集群配置
1)RabbitMQ 集群搭建

环境:有三台主机,主机名和 IP 如下:

live-mq-01:172.18.8.157
live-mq-02:172.18.8.158
live-mq-03:172.18.8.161

同步主机的 /etc/hosts 文件。

172.18.8.157live-mq-01
172.18.8.158live-mq-02
172.18.8.161live-mq-03

在三个节点分别安装 rabbitmq-server,如果是 CentOS 使用 yum 即可,如果是 Debian 使用 apt-get 即可。

1 $apt-getinstall rabbitmq-server

在三个节点分别启动 rabbitmq-server

$service rabbitmq-server start

$rabbitmq-server-detached

同步 erlang.cookie 文件,通过 Erlang 的分布式特性(通过 magic cookie 认证节点)进行 RabbitMQ 集群,各 RabbitMQ 服务为对等节点,即每个节点都提供服务给客户端连接,进行消息发送与接收。

root@live-mq-01:~# cat /var/lib/rabbitmq/.erlang.cookie
WJLPTHZIMFLJRTOGPYNA
root@live-mq-02:~# cat /var/lib/rabbitmq/.erlang.cookie
WJLPTHZIMFLJRTOGPYNA
root@live-mq-03:~# cat /var/lib/rabbitmq/.erlang.cookie
WJLPTHZIMFLJRTOGPYNA

在 live-mq-01 节点上查看集群信息,此时集群中应只有自己。

root@live-mq-01:~# rabbitmqctl cluster_status
Cluster status of node’rabbit@live-mq-01’…
[
{nodes,[{disc,[‘rabbit@live-mq-01’]}]},
# 集群中的节点,disc 表示为磁盘模式,ram 表示为内存模式
{running_nodes,[‘rabbit@live-mq-01’]},
# 正在运行的集群节点
{cluster_name,<<“rabbit@live-mq-01”>>},
# 集群的名称
{partitions,[]}
]
…done.

下面将 live-mq-01、live-mq-02、live-mq-03 组成集群:

live-mq-02 加入 live-mq-01 节点。

root@live-mq-02:~# rabbitmqctl stop_app
root@live-mq-02:~# rabbitmqctl join_cluster rabbit@live-mq-01
root@live-mq-02:~# rabbitmqctl start_app

live-mq-03 加入 live-mq-01 节点。

root@live-mq-03:~# rabbitmqctl stop_app
root@live-mq-03:~# rabbitmqctl join_cluster rabbit@live-mq-01 –ram
root@live-mq-03:~# rabbitmqctl start_app

此时 live-mq-02 与 live-mq-03 也会自动建立连接,上面我的两个节点,其中 live-mq-02 是磁盘节点,live-mq-03 是内存节点,但 live-mq-01 节点默认是磁盘节点(一个集群中最少要有一个磁盘节点)。如果想把 live-mq-02 由磁盘节点改成内存节点,使用如下 change_cluster_node_type 命令修改即可,但要先 stop:

root@live-mq-02:~# rabbitmqctl stop_app
Stopping node’rabbit@live-mq-02’…
…done.
root@live-mq-02:~# rabbitmqctl change_cluster_node_type ram
Turning’rabbit@live-mq-02’intoaram node…
…done.
root@live-mq-02:~# rabbitmqctl start_app
Starting node’rabbit@live-mq-02’…
…done.

查看集群信息

root@live-mq-01:~# rabbitmqctl cluster_status
Cluster status of node’rabbit@live-mq-01’…
[{nodes,[{disc,[‘rabbit@live-mq-01’]},
{ram,[‘rabbit@live-mq-03′,’rabbit@live-mq-02’]}]},
{running_nodes,[‘rabbit@live-mq-02′,’rabbit@live-mq-03′,’rabbit@live-mq-01’]},
{cluster_name,<<“rabbit@live-mq-01”>>},
{partitions,[]}]
…done.

我们可以看到三个节点都加入了集群中,两个 ram 节点、一个 disc 节点。其中三个节点都在运行中,以及集群名称显示。

2)允许远程用户访问

第一、添加 mq 用户并设置密码

1 root@live-mq-01:~# rabbitmqctl add_user mq 123456

第二、设置 mq 用户为管理员

1 root@live-mq-01:~# rabbitmqctl set_user_tags mq administrator

第三、设置 mq 用户的权限,指定允许访问的 vhost 以及 write/read

root@live-mq-01:~# rabbitmqctl set_permissions -p “/” mq “.*” “.*” “.*”
Setting permissions foruser”live”invhost”/”…
…done.

第四、查看 vhost(/)允许哪些用户访问

root@live-mq-01:~# rabbitmqctl list_permissions -p /
Listing permissions invhost”/”…
mq.*.*.*
…done.

第五、配置允许远程访问的用户,rabbitmq 的 guest 用户默认不允许远程主机访问。

root@live-mq-01:~# cat /etc/rabbitmq/rabbitmq.config
[
{rabbit,[{tcp_listeners,[5672]},{loopback_users,[“mq”]}]}
].

ps:主机 1 设置完以上这些之后,在集群内的机器都会同步此配置,但是 /etc/rabbitmq/rabbitmq.config 文件不会同步。

root@live-mq-02:~# rabbitmqctl list_users
Listing users…
mq[administrator]
…done.

最后,可以选择删除默认 guest 用户(密码也是 guest)

1 root@live-mq-01:~# rabbitmqctl delete_user guest

3)RabbitMQ 退出集群

假设要把 rabbit@live-mq-02 退出集群,在 rabbit@live-mq-02 上执行:

$rabbitmqctl stop_app
$rabbitmqctl reset
$rabbitmqctl start_app

在集群主节点上执行

 $rabbitmqctl forget_cluster_node rabbit@live-mq-02

4)RabbitMQ 集群重启

集群重启时,最后一个挂掉的节点应该第一个重启,如果因特殊原因(比如同时断电),而不知道哪个节点最后一个挂掉。可用以下方法重启:

先在一个节点上执行

$rabbitmqctl force_boot
$service rabbitmq-server start

在其他节点上执行

$service rabbitmq-server start

查看 cluster 状态是否正常(要在所有节点上查询)。

rabbitmqctl cluster_status

如果有节点没加入集群,可以先退出集群,然后再重新加入集群。

上述方法不适合内存节点重启,内存节点重启的时候是会去磁盘节点同步数据,如果磁盘节点没起来,内存节点一直失败。

5)RabbitMQ 开启图形化页面

RabbitMQ 提供了一个非常友好的图形化监控页面插件(rabbitmq_management),让我们可以一目了然看��Rabbit 的状态或集群状态。

分别在三个节点上执行开启 rabbitmq_management 插件的命令,注意开启几个节点在监控页面就可以看见几个节点:

root@live-mq-01:~# rabbitmq-plugins enable rabbitmq_management
root@live-mq-01:~# rabbitmq-plugins list

查看监听端口(插件监控的端口是 15672)

root@live-mq-01:~# netstat -nplt
Active Internet connections(only servers)
Proto Recv-QSend-QLocal Address          Foreign Address        State      PID/Program name
tcp        0      00.0.0.0:4369            0.0.0.0:*              LISTEN      617/epmd       
tcp        0      00.0.0.0:22              0.0.0.0:*              LISTEN      484/sshd       
tcp        0      00.0.0.0:15672          0.0.0.0:*              LISTEN      2220/beam.smp 
tcp        0      00.0.0.0:10050          0.0.0.0:*              LISTEN      595/zabbix_agentd
tcp        0      00.0.0.0:25672          0.0.0.0:*              LISTEN      2220/beam.smp 
tcp6      0      0:::10050                :::*                    LISTEN      595/zabbix_agentd
tcp6      0      0:::5672                :::*                    LISTEN      2220/beam.smp

打开浏览器,直接访问 IP:15672 即可看到 RabbitMQ 的监控画面(输入 mq 用户和密码),如下:

RabbitMQ 两种集群模式配置管理

从图中可以看出集群中的三个节点信息,其中两个内存节点,一个磁盘节点。另外,在 memory 字段显示了当前内存的使用情况和最高可以使用的内存量,同样在 Disk space 字段显示了磁盘空间和最低可用的磁盘空间。基于这两点,下面说一下 RabbitMQ 对内存和磁盘的控制。

一、内存控制

vm_memory_high_watermark 该值为内存阈值,默认为 0.4。意思为物理内存的 40%。40% 的内存并不是内存的最大的限制,它是一个发布的节制,当达到 40% 时 Erlang 会做 GC。最坏的情况是使用内存 80%。如果把该值配置为 0,将关闭所有的 publishing。

root@live-mq-01:~# rabbitmqctl set_vm_memory_high_watermark 0

Paging 内存阈值,该值为默认为 0.5,该值为 vm_memory_high_watermark 的 20% 时,将把内存数据写到磁盘。

如机器内存 16G,当 RABBITMQ 占用内存 1.28G(16*0.4*0.2)时把内存数据放到磁盘。

二、硬盘控制

当 RabbitMQ 的磁盘空闲空间小于 50M(默认),生产者将被 BLOCK。

如果采用集群模式,磁盘节点空闲空间小于 50M 将导致其他节点的生产者都被 block。可以通过 disk_free_limit 来对进行配置。

如果要从远程登录怎么做呢?处于安全考虑,guest 这个默认的用户只能通过 http://localhost:15672 来登录,其他的 IP 无法直接用这个 guest 帐号。这里我们可以通过配置文件来实现从远程登录管理界面,只要编辑 /etc/rabbitmq/rabbitmq.config 文件(没有就新增),添加以下配置就可以了。

[
{rabbit,[{tcp_listeners,[5672]},{loopback_users,[“mq”]}]} 
].

这个操作在上面配置中都已经做过了。

6)注意事项

cookie 在所有节点上必须完全一样,同步时一定要注意。
erlang 是通过主机名来连接服务,必须保证各个主机名之间可以 ping 通。可以通过编辑 /etc/hosts 来手工添加主机名和 IP 对应关系。如果主机名 ping 不通,rabbitmq 服务启动会失败。
如果 queue 是非持久化 queue,则如果创建 queue 的那个节点失败,发送方和接收方可以创建同样的 queue 继续运作。但如果是持久化 queue,则只能等创建 queue 的那个节点恢复后才能继续服务。
在集群元数据有变动的时候需要有 disk node 在线,但是在节点加入或退出的时候所有的 disk node 必须全部在线。如果没有正确退出 disk node,集群会认为这个节点当掉了,在这个节点恢复之前不要加入其它节点。
RabbitMQ 镜像集群配置
上述配置的 RabbitMQ 默认集群模式,但并不包管队列的高可用性,尽管互换机、绑定这些可以复制到集群里的任何一个节点,然则队列内容不会复制。固然该模式解决一项目组节点压力,但队列节点宕机直接导致该队列无法应用,只能守候重启,所以要想在队列节点宕机或故障也能正常应用,就要复制队列内容到集群里的每个节点,须要创建镜像队列。

镜像队列是基于普通的集群模式的,所以你还是得先配置普通集群,然后才能设置镜像队列,我们就以上面的集群接着做。

我是通过上面开启的网页的管理端来设置的镜像队列,也可以通过命令,这里先说其中的网页设置方式:

1、点击 admin 菜单–> 右侧的 Policies 选项–> 左侧最下下边的 Add/update a policy。

2、按照图中的内容根据自己的需求填写。

3、点击 Add policy 添加策略。

此时你就会来你的两台 rabbitmq 服务器的网页管理端 amind 菜单下看见刚才创建的队列了,下面我们来添加一个 queues 队列来看看效果,这里只是测试结果,其它的先不填写。

设置镜像队列策略

在任意一个节点上执行:

1 root@live-mq-01:~# rabbitmqctl set_policy ha-all “^” ‘{“ha-mode”:”all”}’

将所有队列设置为镜像队列,即队列会被复制到各个节点,各个节点状态保持一直。

我们去 live-mq-02 上查看策略。

root@live-mq-02:~# rabbitmqctl list_policies
Listing policies…
/ha-allall^{“ha-mode”:”all”}0
…done.

此时镜像集群就已经完成了,可以在任意节点上创建队列,看看其他两个节点是否会同步。

CentOS 7.2 下 RabbitMQ 集群搭建 http://www.linuxidc.com/Linux/2016-12/137812.htm

CentOS7 环境安装使用专业的消息队列产品 RabbitMQ http://www.linuxidc.com/Linux/2016-11/13673.htm

RabbitMQ 入门教程  http://www.linuxidc.com/Linux/2015-02/113983.htm

在 CentOS7 上安装 RabbitMQ 详解  http://www.linuxidc.com/Linux/2017-05/143765.htm

NServiceBus 结合 RabbitMQ 使用教程  http://www.linuxidc.com/Linux/2017-05/143787.htm

CentOS 7 下 RabbitMQ 集群安装配置  http://www.linuxidc.com/Linux/2017-10/147707.htm

RabbitMQ 实战:高效部署分布式消息队列 中文 PDF 扫描版  http://www.linuxidc.com/Linux/2017-10/147592.htm

RabbitMQ 的详细介绍:请点这里
RabbitMQ 的下载地址:请点这里

本文永久更新链接地址:http://www.linuxidc.com/Linux/2017-10/147708.htm

正文完
星哥说事-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-01-21发表,共计8788字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中