1.设计集群的目的
(1)允许消费者和生产者在RabbitMQ节点崩溃的情况下继续运行;
(2)通过增加更多的节点来扩展消息通信的吞吐量.
2.集群配置方式
Rabbitmq可以通过三种方法来部署分布式集群系统,分别是:cluster,federation,shovel
a)cluster:
不支持跨网段,用于同一个网段内的局域网
可以随意的动态增加或者减少
节点之间需要运行相同版本的Rabbitmq和Erlang
b)federation:
应用于广域网,允许单台服务器上的交换机或者队列接收发布到另外一台服务器上的交换机或队列的消息,可以是单台机器或集群.federation队列类似于单向点对点连接,消息会在联盟队列之间转发任意次,直到被消费者接受.通常使用federation来连接internet上的中间服务器,用作订阅分发消息或者工作队列.
c)shovel:
连接方式与federation的连接方式类似,但它工作在更低层次,可以用于广域网.
3.节点类型
集群中的节点一般有两种,一种是内存节点,一种是磁盘节点,内存节点由于没有磁盘读写,性能比磁盘节点好,磁盘节点可以将状态持久化到磁盘,可用性比内存节点好,需要权衡考虑.本次打算用一台作为磁盘节点,做数据备份,两台内存节点,用于提高性能.
Rabbitmq要求在集群中至少有一个磁盘节点,所有其他节点可以是内存节点,当节点加入或者离开集群时,必须要将该变更通知到至少一个磁盘节点.如果集群中唯一的磁盘节点崩溃的话,集群仍然可以保持运行,但是无法进行其他的操作(增删改查),直到节点恢复.
4.集群模式
普通模式(默认):对于Queue来说,消息实体只存在于其中的一个节点,A/B两个节点仅有相同的元数据,即队列结构.(交换机的所有元数据在所有节点上是一致的,而队列的完整信息只有在创建它的节点上,各个节点仅有相同的元数据,即队列结构)当消息进入A节点的Queue中后,consumer从B节点拉取数据时,RabbitMQ会临时在A.B间进行消息传输,把A中的消息实体取出并经过B发送给consumer.所以consumer应尽量连接每个节点,从中取消息.即对于同一个逻辑队列,要在多个节点建立物理Queue,否则无论consumer连A或B,出口总在A,会产生瓶颈.该模式存在一个问题就是当A节点故障后,B节点无法取到A节点中还未消费的消息实体.如果做个消息持久化,那么等A几点恢复,然后才可被消费;如果没有做持久化,然后就...该模式非常适合非持久化队列,只有该队列是非持久化的,客户端才能重新连接到集群中的其他节点,并且重新创建队列,如果该队列是持久化的,那么唯一的办法就是将故障节点恢复起来.
镜像模式(高可用模式):把需要的队列做成镜像模式,存在于多个节点,数据Rabbitmq的HA方案.该模式解决了上述问题,其实质和普通模式的不同之处在于,消息实体会主动在镜像节点间同步,而不会在consumer取数据时临时拉取.该模式带来的副作用也很明显,除了降低系统性能意外,如果镜像队列过多,加之有大量的消息进入,集群内部的网络带宽将会被这种同步通讯大大消耗掉,所以在对可靠性要求较高的场合中适用.
1.配置hosts
在安装好Rabbitmq的几台机器上,分别修改/etc/hosts文件,必须修改为一样的状态. 例如:
172.17.0.1 rabbitmq1
172.17.0.2 rabbitmq2
172.17.0.3 rabbitmq3
2.配置cookie:
Erlang Cookie是保证不同节点可以互相通信的秘钥,要保证集群中的不同节点互相通信必须共享相同的Erlang Cookie,具体存放在/var/lib/rabbitmq/.erlang.cookie.说明:这就要从rabbitmqctl命令的工作原理说起,rabbitmq底层是通过Erlang架构来实现的,所以rabbitmqctl会启动erlang节点,并基于Erlang节点来使用Erlang系统连接Rabbitmq节点,在连接过程中需要正确的Erlang和节点名称,Erlang节点会通过交换Erlang Cookie以获得认证.
Erlang节点间通过认证Erlang cookie的方式允许互相通信.因为 rabbitmqctl 使用 Erlang OTP 通信机制来和 Rabbit 节点通信,允许rabbitmqctl 的机器和所要连接的Rabbit节点必须使用相同的Erlang cookie.否则,会报错.文件权限要保持一致(400),各节点是通过这个cookie来进行通信的.可以将其中一台节点上.erlang.cookie值scp到其他节点上.具体做法如下:
(1)先备份原有cookie文件,原节点启停rabbitmq-service可以用到.
rabbit02# cp /var/lib/rabbitmq/.erlang.cookie /var/lib/rabbitmq/.erlang.cookie.bak
rabbit03# cp /var/lib/rabbitmq/.erlang.cookie /var/lib/rabbitmq/.erlang.cookie.bak
(2)修改cookie的值:
scp /var/lib/rabbitmq/.erlang.cookie 172.17.0.2:/var/lib/rabbitmq
scp /var/lib/rabbitmq/.erlang.cookie 172.17.0.3:/var/lib/rabbitmq
(3)在复制的时候需要临时修改cookie文件的权限:
chmod 777 /var/lib/rabbitmq/.erlang.cookie
(4)拷贝完毕后再把权限修改回来:
chmod 400 /var/lib/rabbitmq/.erlang.cookie
3.组建集群
停掉所有节点上的rabbitmq服务,然后使用-detached独立运行各个节点,这步很关键,尤其是增加节点停止节点后再次启动遇到无法启动时都可以参照这个顺序进行.
rabbitmqctl stop
rabbitmq-server -detached
查看集群状态:
rabbitmqctl cluster_status
此时都以单个节点的形式运行,{cluster_name,<<"rabbit@rabbitmq1">>},这是集群名字,其他节点可以 join 到这个集群中。所有节点都是平等的,可以加入到任意一个集群中,最终这些节点都会在同一个集群中.
停掉其他rabbitmq节点,执行加入集群的命令:
rabbitmqctl stop_app
rabbitmqctl join_cluster rabbit@rabbitmq1(注意:以内存节点的形式加入集群的命令:
rabbitmqctl join_cluster --ram rabbit@rabbitmq1)
rabbitmqctl start_app
此时再次查看集群状态,可以看到,各节点处于一个由rabbit01(disc node)、rabbit02(ram node)、rabbit03(ram node)组成的集群
rabbitmqctl cluster_status
在管控台界面也可以查看到具体的集群信息.
注意:
(1)如果要将某个节点从集群中移除,使其变回独立节点,可以使用以下命令:
rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl start_app
(2)如果需要启停某个节点来进行维护,可以使用以下命令:
rabbitmqctl stop
rabbitmq-server -detached
(3)若要修改某个节点类型,可以使用以下命令:(使用之前先stop某个节点)
rabbitmqctl stop_app
rabbitmqctl change_cluster_node_type disc
(4)当新的节点加入到集群之后,其用户信息也会被重置了(之前添加的admin账户不见了),需要重新配置管理员用户,以便访问到RabbitMQ管理界面(在任意节点添加用户,会自动同步到各个节点).
添加管理员并授权:
rabbitmqctl add_user admin 123456
rabbitmqctl set_user_tags admin administrator
rabbitmqctl set_permissions -p / admin ".*" ".*" ".*"
rabbitmq-plugins enable rabbitmq_management(开启web管理界面)
(5)退出集群
假设把rabbit@live-mq-02退出集群,在rabbit@live-mq-02上执行:
rabbitmqctl stop_app
在集群主节点上执行:
rabbitmqctl forget_cluster_node rabbit@live-mq-02
4.设置镜像队列策略:
在任意一个节点上执行:
rabbitmqctl set_policy ha-all "^" '{"ha-mode":"all"}'
即所有的队列设置为镜像队列,即队列会被复制到各个节点,各个节点状态保持一致.完成以上步骤以后,Rabbitmq高可用集群就已经搭建好了,最后一个步骤是是搭建负载均衡器.
补充说明:rabbitmqctl set_policy -p hrsystem ha-allqueue "^" '{"ha-mode":"all"}'
这一行命令是在vhost名称为hrsystem创建一个策略,策略名称为ha-allqueue,策略模式为all,即复制到所有节点,包含新增节点,策略表达式为"^",表示所有匹配所有队列名称.
查看策略:rabbitmqctl list_policies -p /
清除策略:rabbitmqctl clear_policy -p / ha-allweb3.0
5.RabbitMQ负载均衡配置---选择开源的HAProxy为RabbitMQ集群做负载均衡器
搭建过程可参考:http://blog.51cto.com/freeloda/1294094
关于配置文件/etc/haproxy/haproxy.cfg的简单说明:
server node1 192.168.1.1:5672 check inter 2000 rise 2 fall 3 //负载均衡中的节点配置,这里选择rabbit节点.
server node2 192.168.1.2:5672 check inter 2000 rise 2 fall 3
#server node2 192.168.1.3:5672 check inter 2000 rise 2 fall 3
负载均衡器会监听5672端口,轮询两个内存节点192.168.1.1和192.168.1.2的5672端口,第三台为磁盘节点,只做备份,不提供给生产者和消费者使用,当然服务器资源充足的情况下也可配置多个磁盘节点,这样磁盘节点出了故障也不会影响.
文末
1.关于集群恢复与故障转移:
从节点停机解决:在主节点执行rabbitmqctl forget_cluster_node slavenode ,然后再把从节点加入集群.
主节点停机恢复:rabbitmqctl forget_cluster_node --offline slavenode执行该命令,支持线下恢复.等主节点恢复,再把从节点加入进去.
2.重要文件存储位置:
/usr/local/rabbitmq_server/var/log/rabbitmq/[email protected]:rabbitmq的崩溃报告
/usr/local/rabbitmq_server/etc/rabbitmq/rabbitmq.config:rabbitmq的配置文件
/usr/local/rabbitmq_server/var/lib/rabbitmq/mnesia/rabbit@tms:rabbit消息持久化文件
/usr/local/rabbitmq_server/var/log/rabbitmq/[email protected]:记录rabbitmq运行日常的日志
3.参考链接:
https://blog.csdn.net/qq_22075041/article/details/78855708
https://88250.b3log.org/rabbitmq-clustering-ha
https://blog.csdn.net/qq_35246620/article/details/72473098
https://my.oschina.net/jiaoyanli/blog/822011
http://www.imooc.com/article/46311
http://chyufly.github.io/blog/2016/04/10/rabbitmq-cluster/
https://www.jianshu.com/p/97fbf9c82872
https://cloud.tencent.com/developer/article/1014974
http://blog.51cto.com/ghbsunny/2154269
http://www.voidcn.com/article/p-vlhrergj-bsb.html
https://mshk.top/2016/08/rabbitmq-haproxy/
http://www.ywnds.com/?p=4741
http://www.rabbitmq.com/rabbitmqctl.8.html
http://www.rabbitmq.com/ha.html
http://www.rabbitmq.com/install-debian.html
https://www.jusene.me/2018/02/28/rabbitmq-3/