准备三台安装了RabbitMQ的节点, 我的三台示例机器配置如下 :
IP hostname 关系
192.168.21.132 node1 主节点
192.168.21.135 node2 镜像节点
192.168.21.136 node3 镜像节点
在主节点配置好MQ的所用队列、交换机、账号等。详细请看:RabbitMQ安装文档
镜像节点安装好MQ不用配置,后面会自动将主节点的配置同步过去。
1.修改每台主机的别名
hostnamectl set-hostname node1
hostnamectl set-hostname node2
hostnamectl set-hostname node3
2.修改每台机器hosts文件
vi /etc/hosts
192.168.21.132 node1
192.168.21.135 node2
192.168.21.136 node3
3.同步erlang.cookie文件
a.同步cookie必须关闭所有MQ服务,每台机器执行关闭命令
systemctl stop rabbitmq-server
a.防止权限不足被拒绝预先修改文件权限,每台机器执行此命令
chmod 600 /var/lib/rabbitmq/.erlang.cookie
a.将node1的cookie同步到node2、node3,在主节点执行命令
scp /var/lib/rabbitmq/.erlang.cookie root@node2:/var/lib/rabbitmq/
scp /var/lib/rabbitmq/.erlang.cookie root@node3:/var/lib/rabbitmq/
b.如果c执行失败,需要手动复制主节点的cookie内容到node2、node3
4.启动每台机器的MQ
systemctl start rabbitmq-server
5.开通要用到的端口
firewall-cmd --zone=public --add-port=4369/tcp --permanent
firewall-cmd --zone=public --add-port=25672/tcp --permanent
a.重启,为了识别出开放的端口
systemctl restart firewalld.service
6.开始集群关系搭建
a.停止node2、node3服务
rabbitmqctl stop_app
b.重置node2、node3的状态,会导致所有数据丢失,不可使用已经在用的MQ进行此操作。(此处使用磁盘方式加入集群必须重置,如果不能重置可用内存方式加入。至少保证一个磁盘节点的存在,当内存节点离开集群将改变通知到磁盘节点,重启后在磁盘节点获取到元数据。)
rabbitmqctl reset
a.从节点加入主节点node1(每个从节点都依次执行命令,加入-启动)
rabbitmqctl join_cluster rabbit@node1
rabbitmqctl start_app
7.查看集群状态
rabbitmqctl cluster_status
a.命令查看结果
如下显示,集群中包含node1、node2、node3,三个节点运行正常
[root@rabbit-node1 keepalived]# rabbitmqctl cluster_status
Cluster status of node rabbit@node1 …
[{nodes,[{disc,[‘rabbit@node1’,‘rabbit@node2’,
‘rabbit@node3’]}]},
{running_nodes,[‘rabbit@node3’,‘rabbit@rnode2’,
‘rabbit@node1’]},
{cluster_name,<<“rabbit@node1”>>},
{partitions,[]},
{alarms,[{‘rabbit@node3’,[]},
{‘rabbit@node2’,[]},
{‘rabbit@node1’,[]}]}]
b.也可以使用UI界面查看:
至此,MQ的集群已经搭建完成,但是只是保证了MQ服务的可用性还并不是高可用的,当master挂了后从节点顶替生产者端和消费者端依然可以正常使用,但是数据是没有进行共享的,例如queue1创建在node1上,node1挂掉后这个队列是不可用的,虽然node2能在UI界面看到这个队列,但是只是共享了元数据,并未实际拥有一样的数据。
为保证数据的不丢失,也就是实际的高可用,此处配置镜像模式。
8.镜像配置
a.任一节点执行此命令即可
rabbitmqctl set_policy ha-all “^” ‘{“ha-mode”:“all”,“ha-sync-mode”:“automatic”}’
在上面我们指定了 ha-mode 的值为 all ,代表消息会被同步到所有节点的相同队列中。这里我们之所以这样配置,因为我们本身只有三个节点,因此复制操作的性能开销比较小。如果你的集群有很多节点,那么此时复制的性能开销就比较大,此时需要选择合适的复制系数。通常可以遵循过半写原则,即对于一个节点数为 n 的集群,只需要同步到 n/2+1 个节点上即可。此时需要同时修改镜像策略为 exactly,并指定复制系数 ha-params
rabbitmqctl set_policy ha-two “^” ‘{“ha-mode”:“exactly”,“ha-params”:2,“ha-sync-mode”:“automatic”}’
此外,RabbitMQ提供了两个参数,可决定在什么情况下从节点晋升为主节点,提供了 ha-promote-on-shutdown,ha-promote-on-failure 两个参数让用户决策是保证队列的可用性,还是保证队列的一致性;两个参数分别控制正常关闭、异常故障情况下从节点是否提升为主节点,其可设置的值为 when-synced 和 always
a.文档配置方式参数说明
晋升策略此文档采用默认值方式,如有需要仔细参考说明后自行调整。
ha-mode":“all” 消息会被同步到所有节点的相同队列中
“ha-sync-mode”:“automatic” 消息自动同步,节点宕掉重启后默认需要手动同步内容,此处采用自动同步。
9.查看镜像状态
10.配置网络分区自动处理
a.查看MQ安装位置
whereis rabbitmq
b.找到rabbitmq.config.example
find / -name rabbitmq.config.example
c.找到rabbitMq-defaults
find / -name rabbitmq-defaults
查看rabbitmq-defaults中CONFIG_FILE指定的配置文件所在位置
将rabbitmq.config.example复制到CONFIG_FILE的指定位置并重命名为rabbitmq.config
d.配置自动处理网络分区 策略-autoheal
修改rabbitmq.config,加入{cluster_partition_handling, autoheal}
停止服务重启
rabbitmqctl stop_app
rabbitmqctl start_app