rabbitmq集群是通过erlang的分布式特性进行rabbitmq集群,各个rabbitmq的服务为相应的节点,每个节点都提供给客户端连接,进行消息的发送与接收。
环境:CentOS 6.8 64位
服务器:192.168.179.128 wangwq01
192.168.179.129 wangwq02
192.168.179.130 wangwq03
1. 主机域名解析
rabbitmq各节点之间通信使用域名,所以集群成员中所有主机名都要可解析,这里使用修改hosts文件来实现解析。
2. 集群的几种实现方法及特性
1)手动使用rabbitmqctl创建
2)通过配置文件来列举出集群的节点
3)使用rabbitmq-autocluster来实现(此为一个插件)
4)使用rabbitmq-cluster来实现(这也是个插件)
集群可以动态构建与修改,即可以动态添加也可以动态脱离。集群中的节点可以随时关闭和启动,也可以允许个别节点出现故障,只要在整个集群中有正常节点即可。
节点可以是磁盘节点,也可以是内存节点,两者之间可以互换使用,一般情况都是磁盘节点,特殊情况下使用内存节点可用于提高队列、交换器或绑定的性能。
3. 设置cookie文件
rabbitmq集群的节点间是使用cookie来确认通信的,所以集群中的每个节点都必须有相同的erlang.cookie,同时保证文件权限是400且所属用户和组都一致
每个rabbitmq启动时,erlang会自动创建一个cookie文件,为了使每个节点的cookie保持一致,可以先让其中一个节点来创建,然后将这个文件拷贝到其他节点的相应位置。默认cookie文件位于/var/lib/rabbitmq/.erlang.cookie
例:192.168.179.130创建了cookie文件,在192.168.179.129上
cd /var/lib/rabbitmq/
如果已经有了该文件,则删除:
rm -rf .erlang.cookie scp [email protected]:/var/lib/rabbitmq/.erlang.cookie ./
查看文件所属用户和组以及权限是否满足要求,不满足则修改,否则会报错:
Error when reading /var/lib/rabbitmq/.erlang.cookie: eacces
chown rabbitmq:rabbitmq .erlang.cookie chmod 400 .erlang.cookie
4. 启动单个节点
运行命令:
rabbitmq-server -detached
可能会出错:ERROR: node with name "rabbit" already running on "hostname"
这是因为已经有一个运行的rabbitmq进程,停止即可:
ps aux|grep rabbitmq kill -15 PID
然后再次运行启动命令。
这三个独立的节点可以通过如下命令来验证:
rabbitmqctl cluster_status
会看到:
Cluster status of node [email protected] ...
[{nodes,[{disc,[[email protected]]}]},
{running_nodes,[[email protected]]},
{cluster_name,<<"[email protected]">>},
{partitions,[]},
{alarms,[{[email protected],[]}]}]
5. 创建集群
要把单独的节点构建到一个集群中,可以暂定其中一个节点为集群中的第一个节点。然后依次将别的节点加入到集群中(只要是已经成为集群中的节点,其他节点就可以通过该节点加入)。举如下例子:
可以暂定[email protected]为集群的第一个节点,先将[email protected]加入到[email protected]的集群中,加入之前必须先停止rabbit02的rabbitmq应用程序,加入之后再启动,然后[email protected]可以通过[email protected]加入,也可通过[email protected]加入集群。
在[email protected]上:
rabbitmqctl stop_app rabbitmqctl join_cluster [email protected] rabbitmqctl start_app
加入过程中可能会遇到错误,如:Error: unable to connect to nodes [[email protected]]: nodedown 这是因为端口未开通导致无法连接到主机,可能是iptables没有设置或者设置不当。
注:加入集群时有两种不同的节点类型:磁盘节点和内存节点。一个集群中至少要有一个磁盘节点,当有节点加入或者离开时,必须要将变更通知到至少一个磁盘节点。如果集群中只有一个磁盘节点或者只剩一个磁盘节点可用,这个磁盘节点崩溃之后,集群扔可保持运行,但无法进行其他操作(增删改查),直到节点恢复。所以集群中最好设置两个或以上的磁盘节点。
默认创建的为磁盘节点,创建内存节点只需要加一个参数[--ram]:
rabbitmqctl join_cluster --ram [email protected]
改变节点类型,如将内存节点更改为磁盘节点:
rabbitmqctl stop_app rabbitmqctl change_cluster_node_type disc rabbitmqctl start_app
如果是开启iptables的,添加如上端口的规则:
vi /etc/sysconfig/iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 4369 -j ACCEPT -A INPUT -m state --state NEW -m tcp -p tcp --dport 25672 -j ACCEPT :wq保存退出 /etc/init.d/iptables restart
这样[email protected]加加入到集群中了,可以通过cluster_status命令查看:
rabbitmqctl cluster_status
如果正常 可看到:
Cluster status of node [email protected] ...
[{nodes,[{disc,[[email protected],[email protected]]}]},
{running_nodes,[[email protected],[email protected]]},
{cluster_name,<<"[email protected]">>},
{partitions,[]},
{alarms,[{[email protected],[]},{[email protected],[]}]}]
在[email protected]上也可查看到相同的信息。
然后将[email protected]加入到集群,这时它既可以选择通过[email protected]来加入,也可以选择[email protected]来加入,因为01和02都是集群的成员了。
在[email protected]上:
rabbitmqctl stop_app rabbitmqctl join_cluster [email protected] rabbitmqctl start_app
在三个节点上分别使用cluster_status命令查看,可看到三个节点都在集群里了。
修改集群的名字:
rabbitmqctl set_cluster_name new_mqname
6. 重启集群节点
加入到集群中的节点,任何时候都允许停止,剩余的节点不受影响继续工作,重新启动停止的节点会再次自动工作
如:停止[email protected]
在rabbit01上:
rabbitmqctl stop
然后在集群的某个节点中查看:
rabbitmqctl cluster_status
Cluster status of node [email protected] ...
[{nodes,[{disc,[[email protected],[email protected],[email protected]]}]},
{running_nodes,[[email protected],[email protected]]},
{cluster_name,<<"[email protected]">>},
{partitions,[]},
{alarms,[{[email protected],[]},{[email protected],[]}]}]
可看到运行的节点中少了[email protected],再次启动rabbit01
rabbitmq-server -detached rabbitmqctl cluster_status
Cluster status of node [email protected] rabbit01 ...
[{nodes,[{disc,[[email protected] rabbit01,[email protected] rabbit02,[email protected] rabbit03]}]},
{running_nodes,[[email protected] rabbit02,[email protected] rabbit03,[email protected] rabbit01]},
{cluster_name,<<"[email protected]">>},
{partitions,[]},
{alarms,[{[email protected] rabbit02,[]},{[email protected] rabbit03,[]},{[email protected] rabbit01,[]}]}]
注意:
1. 当整个集群关闭时,最后一个关闭的节点必须要在下次第一个启动,否则,节点会等待最后一个磁盘节点30s来确认重新连接,连接不到就会失败。如果最后一个关闭的节点无法恢复,可以使用以下命令从集群中删除:
rabbitmqctl forget_cluster_node
2. 如果所有节点都在同一时间关闭(如断电的情况),这会让所有节点都认为其他节点在自己之后,这种情况时,可以在其中的一个节点上执行以下命令使其成为可启动的:
rabbitmqctl force_boot
7. 脱离集群
要删除集群中的节点,首先要停止rabbitmq应用程序,然后重设节点,完成之后再次启动。删除后的节点又会变为独立的节点。
例:将[email protected]从节点中删除
a. 在本节点删除
在rabbit03上:
rabbitmqctl stop_app rabbitmqctl reset rabbitmqctl start_app
然后在节点上执行cluster_status命令来确认是否成功
在rabbit01上:
rabbitmqctl cluster_status
Cluster status of node [email protected] ...
[{nodes,[{disc,[[email protected],[email protected]]}]},
{running_nodes,[[email protected],[email protected]]},
{cluster_name,<<"[email protected]">>},
{partitions,[]},
{alarms,[{[email protected],[]},{[email protected],[]}]}]
在rabbit03上查看:
rabbitmqctl cluster_status
Cluster status of node [email protected] ...
[{nodes,[{disc,[[email protected]]}]},
{running_nodes,[[email protected]]},
{cluster_name,<<"[email protected]">>},
{partitions,[]},
{alarms,[{[email protected],[]}]}]
b. 远程删除
如在rabbit02上删除rabbit03(依然要先停止应用程序)
在rabbit03上停止:
rabbitmqctl stop_app
在rabbit02上删除:
rabbitmqctl forget_cluster_node [email protected]
这时集群中已经将rabbit03删除了,但是rabbit03本身还不知道,依然认为自己是集群中的一员,所以启动时会报错:
Error description:
{error,{inconsistent_cluster,"Node [email protected] thinks it‘s clustered with node [email protected], but [email protected] disagrees"}}
想要让rabbit03再次成为单独可使用的节点,需要进行重置。
在rabbit03上:
rabbitmqctl reset
然后再次启动:
rabbitmqctl start_app