本人所负责的系统是分布式系统,用到了消息队列rabbitmq。起初为了快速验证业务功能,只简单部署了一台rabbitmq服务器,显然存在着单点故障风险,无法应用于生产环境。本人结合项目实际情况经过一翻研究,决定对rabbitmq服务器进行集群部署,进一步部署nginx负载均衡代理转发,实现服务高可用。此篇为系列第三篇rabbitmq集群篇。
rabbitmq安装需要erlang环境,并且两者之间的版本需要正确匹配。这里采用的版本为RabbitMQ 3.9.7和Erlang 24.0。安装过程采用root用户进行操作,linux环境为centos版本7。
rabbitmq集群部署之路【一】erlang安装篇(https://blog.csdn.net/guiripei/article/details/124318028),已经安装了erlang。
rabbitmq集群部署之路【二】rabbitmq安装篇(https://blog.csdn.net/guiripei/article/details/124347066),已经安装了rabbitmq。
本篇继续rabbitmq集群部署,操作步骤及截图详情描述如下。
我所在的项目主机如下:
node20 192.168.100.20
node21 192.168.100.21
node22 192.168.100.22
rabbitmq集群部署官网有详细的描述,详见https://www.rabbitmq.com/clustering.html,英文不好的看起来让人发懵,但把页面翻译后还可以读一读。整篇文章读下来,有几点关键信息:
一、群集中的节点名称必须是唯一的,即linux系统的主机名(/etc/hostname)必须命名唯一。
二、群集中的节点采用Erlang Cookie进行身份验证。为了使两个节点能够进行通信,它们必须具有相同的共享密钥,称为Erlang cookie。每个群集节点必须具有相同的 Cookie。
三、节点计数和仲裁,由于一些功能(例如仲裁队列、MQTT 中的客户端跟踪)需要在集群成员之间达成共识,因此强烈建议使用奇数个集群节点:1、3、5、7 等。这点跟hadoop、zookeeper一样,少数服从多数。
四、磁盘节点disc和内存节点ram。RAM 节点仅将内部数据库表存储在内存中,如果群集停止,将丢失所有数据。默认采用的是磁盘节点disc,即镜像集群模式。本项目部署是磁盘节点disc方式。
1、修改主机名(/etc/hostname)和主机域名映射IP地址(/etc/hosts)
vim /etc/hostname
vim /etc/hosts
修改后如图所示。
2、复制.erlang.cookie
群集中的节点采用Erlang Cookie进行身份验证。为了使两个节点能够进行通信,它们必须具有相同的共享密钥,称为Erlang cookie。每个群集节点必须具有相同的 Cookie。简单来说,部署了Erlang cookie后,各节点之间的通信就免输入密码,这点跟hadoop也是一样的。
本项目以node20主机为主节点,node21主机和node22主机作为从节点加入node20形成集群。
查询一下.erlang.cookie在哪里,命令:find / -name .erlang.cookie
[root@node20 ~]# find / -name .erlang.cookie
/root/.erlang.cookie
[root@node20 ~]# cd /root
[root@node20 ~]# cp .erlang.cookie .erlang.cookie20220421
.erlang.cookie的内容为一个字符串,例如 ZCSLRESSHTLTQOXGTJQO
将node20节点的.erlang.cookie文件内容上传并复制到node21节点、node22节点,命令:
scp /root/.erlang.cookie root@node21:/root/
scp /root/.erlang.cookie root@node22:/root/
提示需要输入远程主机的root用户的密码,如图所示。
3、组建集群
node21节点加入node20节点,形成集群。命令如下:
[root@node21 ~]# cd /rabbitmq_server-3.9.7/sbin
[root@node21 sbin]# ./rabbitmqctl stop_app
Stopping rabbit application on node rabbit@node21 ...
[root@node21 sbin]# ./rabbitmqctl reset
Resetting node rabbit@node21 ...
[root@node21 sbin]# ./rabbitmqctl join_cluster rabbit@node20
Clustering node rabbit@node21 with rabbit@node20
node22节点加入node20节点,形成集群。命令如下:
[root@node22 ~]# cd /rabbitmq_server-3.9.7/sbin
[root@node22 sbin]# ./rabbitmqctl stop_app
Stopping rabbit application on node rabbit@node22 ...
[root@node22 sbin]# ./rabbitmqctl reset
Resetting node rabbit@node22 ...
[root@node22 sbin]# ./rabbitmqctl join_cluster rabbit@node20
Clustering node rabbit@node22 with rabbit@node20
最后的集群效果如图所示:
4、设置镜像集群
通过上面的命令行操作后,还没有形成镜像集群,需要设置一下策略。
登录node20的rabbitmq控制台,按如图所示进行配置,如图所示。
Admin -> Policies -> Add / update a policy
Name:ecg-queue-policy
Pattern:^
Definition:ha-mode=all
4、退出集群
在node20节点操作,将node22删除出集群,命令:
[root@node20 sbin]# ./rabbitmqctl forget_cluster_node rabbit@node22
Removing node rabbit@node22 from the cluster
Error:
RabbitMQ on node rabbit@node22 must be stopped with 'rabbitmqctl -n rabbit@node22 stop_app' before it can be removed
[root@node20 sbin]# ./rabbitmqctl -n rabbit@node22 stop_app
Stopping rabbit application on node rabbit@node22 ...
[root@node20 sbin]# ./rabbitmqctl forget_cluster_node rabbit@node22
Removing node rabbit@node22 from the cluster
[root@node20 sbin]# ./rabbitmqctl -n rabbit@node22 start_app
Starting node rabbit@node22 ...
Error:
{:rabbit, {{:inconsistent_cluster, 'Node rabbit@node22 thinks it\'s clustered with node rabbit@node21, but rabbit@node21 disagrees'}, {:rabbit, :start, [:normal, []]}}}
[root@node20 sbin]#
node20将node22删除出集群后,但node22认为它跟node21是形成集群的,但node21可不这么认为,所以需要对node22进行重置。
[root@node22 ~]# cd /rabbitmq_server-3.9.7/sbin
[root@node22 sbin]# ./rabbitmqctl reset
Resetting node rabbit@node22 ...
[root@node22 sbin]# ./rabbitmqctl start_app
Starting node rabbit@node22 ...
[root@node22 sbin]#
node22退出群集后,最后的效果如图所示。
同样的,也将node21删除出集群。
[root@node20 sbin]# ./rabbitmqctl forget_cluster_node rabbit@node21
Removing node rabbit@node21 from the cluster
Error:
RabbitMQ on node rabbit@node21 must be stopped with 'rabbitmqctl -n rabbit@node21 stop_app' before it can be removed
[root@node20 sbin]# ./rabbitmqctl -n rabbit@node21 stop_app
Stopping rabbit application on node rabbit@node21 ...
[root@node20 sbin]# ./rabbitmqctl forget_cluster_node rabbit@node21
Removing node rabbit@node21 from the cluster
[root@node20 sbin]# ./rabbitmqctl -n rabbit@node21 start_app
Starting node rabbit@node21 ...
Error:
{:rabbit, {{:inconsistent_cluster, 'Node rabbit@node21 thinks it\'s clustered with node rabbit@node20, but rabbit@node20 disagrees'}, {:rabbit, :start, [:normal, []]}}}
[root@node20 sbin]#
node20将node21删除出集群后,但node21认为它跟node20是形成集群的,但node20可不这么认为,所以需要对node21进行重置。
[root@node21 ~]# cd /rabbitmq_server-3.9.7/sbin
[root@node21 sbin]# ./rabbitmqctl reset
Resetting node rabbit@node21 ...
[root@node21 sbin]# ./rabbitmqctl start_app
Starting node rabbit@node21 ...
[root@node21 sbin]#
至此,群集已完全解除。
5、再次形成集群
在node21上面操作,加入node20形成集群。
[root@node21 sbin]# ./rabbitmqctl stop_app
Stopping rabbit application on node rabbit@node21 ...
[root@node21 sbin]# ./rabbitmqctl join_cluster rabbit@node20
Clustering node rabbit@node21 with rabbit@node20
[root@node21 sbin]# ./rabbitmqctl start_app
Starting node rabbit@node21 ...
在node20上面操作,加入node20形成集群。
[root@node22 sbin]# ./rabbitmqctl stop_app
Stopping rabbit application on node rabbit@node22 ...
[root@node22 sbin]# ./rabbitmqctl join_cluster rabbit@node20
Clustering node rabbit@node22 with rabbit@node20
14:14:42.380 [warn] Feature flags: the previous instance of this node must have failed to write the `feature_flags` file at `/rabbitmq_server-3.9.7/var/lib/rabbitmq/mnesia/rabbit@node22-feature_flags`:
14:14:42.388 [warn] Feature flags: - list of previously enabled feature flags now marked as such: [:maintenance_mode_status]
14:14:42.389 [error] Failed to create a tracked connection table for node :rabbit@node22: {:node_not_running, :rabbit@node22}
14:14:42.389 [error] Failed to create a per-vhost tracked connection table for node :rabbit@node22: {:node_not_running, :rabbit@node22}
14:14:42.389 [error] Failed to create a per-user tracked connection table for node :rabbit@node22: {:node_not_running, :rabbit@node22}
[root@node22 sbin]# ./rabbitmqctl start_app
Starting node rabbit@node22 ...
[root@node22 sbin]#
最后的集群效果如图所示:
至此,rabbitmq集群部署成功。