RabbitMQ集群模式
rabbitmq有3种模式,但集群模式是2种。详细如下:
- 单一模式:即单机情况不做集群,就单独运行一个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节点恢复,然后才可被消费;如果没有持久化的话,就会产生消息丢失的现象。
- 镜像模式:把需要的队列做成镜像队列,存在与多个节点属于RabbitMQ的HA方案。该模式解决了普通模式中的问题,其实质和普通模式不同之处在于,消息实体会主动在镜像节点间同步,而不是在客户端取数据时临时拉取。该模式带来的副作用也很明显,除了降低系统性能外,如果镜像队列数量过多,加之大量的消息进入,集群内部的网络带宽将会被这种同步通讯大大消耗掉。所以在对可靠性要求较高的场合中适用。
RabbitMQ实现集群的关键
erlang.cookie
是erlang实现分布式的必要文件,erlang分布式的每个节点上要保持相同的.erlang.cookie
文件,同时保证文件的权限是400。
官方在介绍集群的文档中提到过.erlang.cookie一般会存在这两个地址:
第一个是$home/.erlang.cookie
;
第二个地方就是/var/lib/rabbitmq/.erlang.cookie
。
如果我们使用解压缩方式安装部署的rabbitmq,那么这个文件会在${home}目录下,也就是$home/.erlang.cookie
。
如果我们使用rpm等安装包方式进行安装的,那么这个文件会在/var/lib/rabbitmq
目录下。
我们可以通过rabbitmq的启动日志查看其home dir
目录是哪里,就可以知道.erlang.cookie
存放在哪里,以及mnesia
数据库信息存在哪里。
1 2 3 4 5 6 7 8 |
=INFO REPORT==== 21-Sep-2016::21:17:42 === node : rabbit@he07 home dir : /var/lib/rabbitmq # erlang.cookie存放发地址 config file(s) : /etc/rabbitmq/rabbitmq.config cookie hash : qhOGp9TtH4Rn+BekiYXxIg== log : /var/log/rabbitmq/rabbit@he07.log sasl log : /var/log/rabbitmq/rabbit@he07-sasl.log database dir : /var/lib/rabbitmq/mnesia/rabbit@he07 |
组成普通集群
环境
IP地址 | 主机名 | 操作系统 | 防火墙和SELinux | 用途 |
---|---|---|---|---|
192.168.100.143 | mq01 | CentOS7.4(64位) | 关闭 | 磁盘节点 |
192.168.100.144 | mq02 | CentOS7.4(64位) | 关闭 | 内存节点 |
192.168.100.145 | mq03 | CentOS7.4(64位) | 关闭 | 内存节点 |
1. 配置hosts文件
更改三台MQ节点的计算机名分别为mq01、mq02 和mq03,然后修改hosts配置文件
1 2 3 4 5 6 7 |
vim /etc/hostname //其他两台相同 mq01.localdomain vi /etc/hosts 192.168.100.143 mq01 //注意不能带.注意-主机名称也要更改 192.168.100.144 mq02 192.168.100.145 mq03 |
2.三个节点配置yum源,安装rabbitmq软件
1 2 3 |
yum install -y epel-release yum install -y rabbitmq-server |
Rabbitmq的集群是依附于erlang的集群来工作的,所以必须先构建起erlang的集群景象。Erlang的集群中各节点是经由过程一个magic cookie来实现的,这个cookie存放在/var/lib/rabbitmq/.erlang.cookie
中,文件是400的权限。所以必须保证各节点cookie一致,不然节点之间就无法通信。
1 2 |
[root@mq01 ~]# cat /var/lib/rabbitmq/.erlang.cookie XAHPZVPYUQDWWJIOHUPQ |
用scp
的方式将mq01节点的.erlang.cookie的值复制到其他两个节点中。
1 2 3 |
scp /var/lib/rabbitmq/.erlang.cookie root@192.168.100.144:/var/lib/rabbitmq/.erlang.cookie scp /var/lib/rabbitmq/.erlang.cookie root@192.168.100.145:/var/lib/rabbitmq/.erlang.cookie |
4.分别查看三个节点并添加管理服务,最后启动rabbitmq服务
RabbitMQ提供了一个非常友好的图形化监控页面插件(rabbitmq_management),让我们可以一目了然看见Rabbit的状态或集群状态。
1 2 3 4 5 |
/usr/lib/rabbitmq/bin/rabbitmq-plugins list //查看插件安装情况 /usr/lib/rabbitmq/bin/rabbitmq-plugins enable rabbitmq_management //启用rabbitmq_management服务 service rabbitmq-server start |
5.查看监听端口(插件监控的端口是15672)
1 2 3 |
$ netstat -antp|grep 15672 tcp 0 0.0.0.0:15672 0.0.0.0:* LISTEN 2988/beam |
6.将mq02、mq03作为内存节点加入mq01节点集群中
在mq02、mq03执行如下命令:
1 2 3 4 5 |
rabbitmqctl stop_app //停掉rabbit应用 rabbitmqctl join_cluster --ram rabbit@mq01 //加入到磁盘节点 rabbitmqctl start_app //启动rabbit应用 |
(1)默认rabbitmq启动后是磁盘节点,在这个cluster命令下,mq02和mq03是内存节点,mq01是磁盘节点。
(2)如果要使mq02、mq03都是磁盘节点,去掉–ram参数即可。
(3)如果想要更改节点类型,可以使用命令rabbitmqctl change_cluster_node_type disc(ram)
,前提是必须停掉rabbit应用
7.查看集群状态
选择其中一个节点,执行以下命令:
1 |
rabbitmqctl cluster_status |
8.登录rabbitmq web管理控制台
打开浏览器输入http://192.168.100.143:15672, 输入默认的Username:guest,输入默认的Password:guest ,登录后出现如图所示的界面。
RabbitMQ镜像集群配置
上面已经完成RabbitMQ默认集群模式,但并不保证队列的高可用性,尽管交换机、绑定这些可以复制到集群里的任何一个节点,但是队列内容不会复制。虽然该模式解决一项目组节点压力,但队列节点宕机直接导致该队列无法应用,只能等待重启,所以要想在队列节点宕机或故障也能正常应用,就要复制队列内容到集群里的每个节点,必须要创建镜像队列。
镜像队列是基于普通的集群模式的,然后再添加一些策略,所以你还是得先配置普通集群,然后才能设置镜像队列,我们就以上面的集群接着做。
设置的镜像队列可以通过rabbitmq web管理控制台设置,也可以通过命令。
通过命令设置
命令格式:rabbitmqctl set_policy ha-all
“匹配符” ‘{“ha-mode”:”all”}’
举例:
1 |
rabbitmqctl set_policy ha-all "^" '{"ha-mode":"all"}' |
参数意思为:
ha-all
:为策略名称。
^
:为匹配符,只有一个^代表匹配所有,^zlh
为匹配名称为zlh的exchanges或者queue。
ha-mode
:为匹配类型,他分为3种模式:
all
:所有(所有的queue),exctly
:部分(需配置ha-params
参数,此参数为int类型比如3,众多集群中的随机3台机器),nodes
:指定(需配置ha-params
参数,此参数为数组类型比如[“3rabbit@F”,”rabbit@G”]这样指定为F与G这2台机器。)
通过rabbitmq web管理控制台设置
在mq01节点的控制台上创建策略
(1)点击admin菜单–>右侧的Policies选项–>左侧最下下边的Add/update a policy。
Name
:策略名称Pattern
:匹配的规则,这里表示匹配a开头的队列,如果是匹配所有的队列,那就是^.
Definition
:使用ha-mode
模式中的all
,也就是同步所有匹配的队列。问号链接帮助文档。
测试
此时分别登陆mq02、mq03两个节点的控制台,可以看到上面添加的这个策略,如图所示:
添加队列
在mq01节点的控制台上添加队列
(1)点击Queues菜单–>左侧下边的Add a new queue
(2)输入Name和Arguments参数的值,别的值默认即可
Name
:队列名称Durability
:队列是否持久化Node
:消息队列的节点Auto delete
:自动删除Arguments
:使用的策略类型
(3)点击Add queue
创建消息
(1)点击ab队列按钮
(2)拖动滚动条,点击publish message
(3)填写相关内容
2-Persistent
:表示持久化Headers
:随便填写即可Properties
:点击问号,选择一个消息ID号Payload
:消息内容
(4)点击Publish message按钮
点击queue按钮,发现ab队列的Ready和Total中多了一条消息记录。
做破坏性测试
(1)将mq01节点的服务关闭,再通过mq02和mq03查看消息记录是否还存在。
1 |
rabbitmqctl stop_app //停掉mq01的rabbit应用 |
从中可以看到ab队列已经从之前的+2显示成+1了,而且消息记录是存在的。
(2)再将mq02节点的服务关闭,通过mq03查看消息记录是否还存在。
1 |
rabbitmqctl stop_app //停掉mq02的rabbit应用 |
从中可以看到ab队列和消息记录还是存在的,只是变成了一个节点了。
(3)将mq01和mq02的服务再启动起来
1 |
rabbitmqctl start_app //启动mq01、mq02的rabbit应用 |
从中可以看到ab队列后面+2变成了粉色,鼠标指上去显示镜像无法同步。如果这时候停掉mq03节点的服务,那么队列里面的消息将会丢失。
采取的解决办法是选择在mq02节点上执行同步命令。
1 |
rabbitmqctl sync_queue ab //同步ab队列 |
这样,我们就测试了rabbitmq集群的破坏性测试,说明集群配置成功。
参考
RabbitMQ集群搭建
Rabbitmq集群高可用部署详细