首页 > 代码库 > RabbitMQ集群搭建

RabbitMQ集群搭建

    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 root@192.168.179.130:/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 rabbit@rabbit01 ...

[{nodes,[{disc,[rabbit@rabbit01]}]},

 {running_nodes,[rabbit@rabbit01]},

 {cluster_name,<<"rabbit@localhost">>},

 {partitions,[]},

 {alarms,[{rabbit@rabbit01,[]}]}]


5. 创建集群

    要把单独的节点构建到一个集群中,可以暂定其中一个节点为集群中的第一个节点。然后依次将别的节点加入到集群中(只要是已经成为集群中的节点,其他节点就可以通过该节点加入)。举如下例子:

可以暂定rabbit@rabbit01为集群的第一个节点,先将rabbit@rabbit02加入到rabbit@rabbit01的集群中,加入之前必须先停止rabbit02rabbitmq应用程序,加入之后再启动,然后rabbit@rabbit03可以通过rabbit@rabbit01加入,也可通过rabbit@rabbit02加入集群。

rabbit@rabbit02上:

rabbitmqctl stop_app
rabbitmqctl join_cluster rabbit@rabbit01
rabbitmqctl start_app

    加入过程中可能会遇到错误,如:Error: unable to connect to nodes [rabbit@rabbit01]: nodedown  这是因为端口未开通导致无法连接到主机,可能是iptables没有设置或者设置不当。

 

注:加入集群时有两种不同的节点类型:磁盘节点和内存节点。一个集群中至少要有一个磁盘节点,当有节点加入或者离开时,必须要将变更通知到至少一个磁盘节点。如果集群中只有一个磁盘节点或者只剩一个磁盘节点可用,这个磁盘节点崩溃之后,集群扔可保持运行,但无法进行其他操作(增删改查),直到节点恢复。所以集群中最好设置两个或以上的磁盘节点。

默认创建的为磁盘节点,创建内存节点只需要加一个参数[--ram]

rabbitmqctl join_cluster --ram rabbit@rabbit01

改变节点类型,如将内存节点更改为磁盘节点:

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


这样rabbit@rabbit02加加入到集群中了,可以通过cluster_status命令查看:

rabbitmqctl cluster_status

如果正常 可看到:

Cluster status of node rabbit@rabbit02 ...

[{nodes,[{disc,[rabbit@rabbit01,rabbit@rabbit02]}]},

 {running_nodes,[rabbit@rabbit01,rabbit@rabbit02]},

 {cluster_name,<<"rabbit@localhost">>},

 {partitions,[]},

 {alarms,[{rabbit@rabbit01,[]},{rabbit@rabbit02,[]}]}]

rabbit@rabbit01上也可查看到相同的信息。

然后将rabbit@rabbit03加入到集群,这时它既可以选择通过rabbit@rabbit01来加入,也可以选择rabbit@rabbit02来加入,因为0102都是集群的成员了。

rabbit@rabbit03上:

rabbitmqctl stop_app
rabbitmqctl join_cluster rabbit@rabbit02
rabbitmqctl start_app

在三个节点上分别使用cluster_status命令查看,可看到三个节点都在集群里了。


修改集群的名字:

rabbitmqctl set_cluster_name new_mqname


6. 重启集群节点

加入到集群中的节点,任何时候都允许停止,剩余的节点不受影响继续工作,重新启动停止的节点会再次自动工作

如:停止rabbit@rabbit01

rabbit01上:

rabbitmqctl stop

然后在集群的某个节点中查看:

rabbitmqctl cluster_status

Cluster status of node rabbit@rabbit02 ...

[{nodes,[{disc,[rabbit@rabbit01,rabbit@rabbit02,rabbit@rabbit03]}]},

 {running_nodes,[rabbit@rabbit03,rabbit@rabbit02]},

 {cluster_name,<<"rabbit@localhost">>},

 {partitions,[]},

 {alarms,[{rabbit@rabbit03,[]},{rabbit@rabbit02,[]}]}]

可看到运行的节点中少了rabbit@rabbit01,再次启动rabbit01

rabbitmq-server -detached
rabbitmqctl cluster_status

Cluster status of node rabbit@ rabbit01 ...

[{nodes,[{disc,[rabbit@ rabbit01,rabbit@ rabbit02,rabbit@ rabbit03]}]},

 {running_nodes,[rabbit@ rabbit02,rabbit@ rabbit03,rabbit@ rabbit01]},

 {cluster_name,<<"rabbit@localhost">>},

 {partitions,[]},

 {alarms,[{rabbit@ rabbit02,[]},{rabbit@ rabbit03,[]},{rabbit@ rabbit01,[]}]}]


注意:

    1. 当整个集群关闭时,最后一个关闭的节点必须要在下次第一个启动,否则,节点会等待最后一个磁盘节点30s来确认重新连接,连接不到就会失败。如果最后一个关闭的节点无法恢复,可以使用以下命令从集群中删除:

rabbitmqctl forget_cluster_node

    2. 如果所有节点都在同一时间关闭(如断电的情况),这会让所有节点都认为其他节点在自己之后,这种情况时,可以在其中的一个节点上执行以下命令使其成为可启动的:

rabbitmqctl force_boot


7. 脱离集群

要删除集群中的节点,首先要停止rabbitmq应用程序,然后重设节点,完成之后再次启动。删除后的节点又会变为独立的节点。

例:将rabbit@rabbit03从节点中删除

a. 在本节点删除

rabbit03上:

rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl start_app

然后在节点上执行cluster_status命令来确认是否成功

rabbit01上:

rabbitmqctl cluster_status

Cluster status of node rabbit@rabbit01 ...

[{nodes,[{disc,[rabbit@rabbit01,rabbit@rabbit02]}]},

 {running_nodes,[rabbit@rabbit02,rabbit@rabbit01]},

 {cluster_name,<<"rabbit@localhost">>},

 {partitions,[]},

 {alarms,[{rabbit@rabbit02,[]},{rabbit@rabbit01,[]}]}]


rabbit03上查看:

rabbitmqctl cluster_status

Cluster status of node rabbit@rabbit03 ...

[{nodes,[{disc,[rabbit@rabbit03]}]},

 {running_nodes,[rabbit@rabbit03]},

 {cluster_name,<<"rabbit@rabbit03">>},

 {partitions,[]},

 {alarms,[{rabbit@rabbit03,[]}]}]


b. 远程删除

如在rabbit02上删除rabbit03(依然要先停止应用程序)

rabbit03上停止:

rabbitmqctl stop_app

rabbit02上删除:

rabbitmqctl forget_cluster_node rabbit@rabbit03

这时集群中已经将rabbit03删除了,但是rabbit03本身还不知道,依然认为自己是集群中的一员,所以启动时会报错:

Error description:

   {error,{inconsistent_cluster,"Node rabbit@rabbit03 thinks it‘s clustered with node rabbit@rabbit02, but rabbit@rabbit02 disagrees"}}

想要让rabbit03再次成为单独可使用的节点,需要进行重置。

rabbit03上:

rabbitmqctl reset

然后再次启动:

rabbitmqctl start_app


本文出自 “我不是我” 博客,请务必保留此出处http://wangwq.blog.51cto.com/8711737/1951185

RabbitMQ集群搭建