RabbitMQ是用erlang开发的,集群非常方便,因为erlang天生就是一门分布式语言。
RabbitMQ的集群节点包括内存节点、磁盘节点。顾名思义内存节点就是将所有数据放在内存,磁盘节点将数据放在磁盘。不过,如前文所述,如果在投递消息时,打开了消息的持久化,那么即使是内存节点,数据还是安全的放在磁盘。
良好的设计架构可以如下:在一个集群里,有3台机器,其中1台使用磁盘模式,另2台使用内存模式。2台内存模式的节点,无疑速度更快,因此客户端(consumer、producer)连接访问它们。而磁盘模式的节点,由于磁盘IO相对较慢,因此仅作数据备份使用。
配置RabbitMQ集群非常简单,就几个命令。我没有多余的测试机,就用2台测试,hostname分别是dwdns1和dwdns5,配置步骤如下:
(1)在两台机的/etc/hosts文件里,指定dwdns1和dwdns5的hosts,如:
192.168.1.100 dwdns1
192.168.1.101 dwdns5
还有/etc/hostname文件也要正确,分别是dwdns1和dwdns5。
请注意RabbitMQ集群节点必须在同一个网段里,如果是跨广域网效果就差。
(2)在两台机上都安装和启动RabbitMQ,具体见前文描述。
(3)将dwdns5的/var/lib/rabbitmq/.erlang.cookie这个文件,拷贝到dwdns1的同一位置(反过来亦可),该文件是集群节点进行通信的验证密钥,所有节点必须一致。拷完后重启下RabbitMQ。
(4)假设将dwdns1和dwdns5连接起来,在dwdns1上,执行如下命令:
rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl cluster rabbit@dwdns5
rabbitmqctl start_app
上述命令先停掉rabbitmq应用,reset集群状态,然后调用cluster命令,将dwdns1连接到dwdns5,使两者成为一个集群,最后重启rabbitmq应用。在这个cluster命令下,dwdns1是内存节点,dwdns5是磁盘节点(RabbitMQ启动后,默认是磁盘节点)。
如果要使dwdns1在集群里也是磁盘节点,那么更改上述第3句如下:
rabbitmqctl cluster rabbit@dwdns5 rabbit@dwdns1
只要在节点列表里包含了自己,它就成为一个磁盘节点。在RabbitMQ集群里,必须至少有一个磁盘节点存在。
(5)在dwdns1和dwdns5上,运行cluster_status命令查看集群状态:
root@dwdns1:~# rabbitmqctl cluster_status
Cluster status of node rabbit@dwdns1 …
[{nodes,[{disc,[rabbit@dwdns1,rabbit@dwdns5]}]},
{running_nodes,[rabbit@dwdns5,rabbit@dwdns1]}]
…done.root@dwdns5:~# rabbitmqctl cluster_status
Cluster status of node rabbit@dwdns5 …
[{nodes,[{disc,[rabbit@dwdns1,rabbit@dwdns5]}]},
{running_nodes,[rabbit@dwdns1,rabbit@dwdns5]}]
…done.
我们看到,dwdns1和dwdns5都是磁盘节点(disc),并且都是在运行中的节点(running_nodes)。
(6)往一台集群节点里写入消息队列,会复制到另一个节点上,我们看到两个节点的消息队列数一致:
root@dwdns1:~# rabbitmqctl list_queues -p /pyhtest
Listing queues …
pyh_queue 6100000
…done.root@dwdns5:~# rabbitmqctl list_queues -p /pyhtest
Listing queues …
pyh_queue 6100000
…done.
这样RabbitMQ集群就正常工作了。
如果是3台配置集群,比如host1、host2、host3,那么只要保证host2与host1连通,host3与host1连通就行,host2与host3会自动连通,具体配置方法与2台是一致的