3.3、复制 Erlang cookie
RabbitMQ 集群环境下,元数据同步基于 cookie 共享方案实现。
在这里将 node1 的 cookie 文件复制到 node2,由于这个文件权限是 400 为方便传输,先修改权限,非必须操作,所以需要先修改 node1 中的该文件权限为 777
chmod 777 /var/lib/rabbitmq/.erlang.cookie
用 scp 拷贝到节点 2,节点 3 的操作也类似。
scp /var/lib/rabbitmq/.erlang.cookie node2:/var/lib/rabbitmq/
最后,将权限改回来
chmod 400 /var/lib/rabbitmq/.erlang.cookie
3.4、组成集群
在节点 2 执行如下命令:
# 停止rabbitmq服务 rabbitmqctl stop_app # 清空节点状态 rabbitmqctl reset # node2和node1构成集群,node2必须能通过node1的主机名ping通 rabbitmqctl join_cluster rabbit@node1 # 开启rabbitmq服务 rabbitmqctl start_app
节点 3 的操作也类似!
在任意一台机上面查看集群状态:
rabbitmqctl cluster_status
- 第一行:表示当前节点信息
- 第二行:表示集群中的节点成员,disc 表示这些都是磁盘节点
- 第三行:表示正在运行的节点成员
登录可视化管控台,可以很清晰的看到,三个服务节点已经互相关联起来了!
如果你想将某个节点移除集群,以移除节点3为例,可以按照如下方式进行操作!
# 首先停止要移除的节点服务 rabbitmqctl stop # 移除节点3 rabbitmqctl -n rabbit@node1 forget_cluster_node rabbit@node3
如果移除之后,无法启动 rabbitMQ,删除已有 mnesia 信息!
rm -rf /var/lib/rabbitmq/mnesia
然后再次重启服务即可!
3.5、设置内存节点
#加入时候设置节点为内存节点(默认加入的为磁盘节点) rabbitmqctl join_cluster rabbit@node1 --ram
其中--ram
指的是作为内存节点,如果不加,那就默认为磁盘节点。
如果节点在集群中已经是磁盘节点了,通过以下命令可以将节点改成内存节点:
# 停止rabbitmq服务 rabbitmqctl stop_app # 更改节点为内存节点 rabbitmqctl change_cluster_node_type ram # 开启rabbitmq服务 rabbitmqctl start_app
3.6、镜像队列
上面我们提到,在默认情况下,队列只会保存在其中一个节点上,当节点发生故障时,尽管所有元数据信息都可以从磁盘节点上将元数据恢复到本节点上,但是内存节点的队列消息内容就不行了,这样就会导致消息的丢失。
RabbitMQ 很早就意识到这个问题,在 2.6 以后的版本中增加了队列冗余选项:镜像队列。
所谓镜像队列,其实就是主队列(master)依然是仅存在于一个节点上,通过关联的 rabbitMQ 服务器,从主队列同步消息到各个节点,也就是所谓的主从模式,将主队列的消息进行备份处理。
如果主队列没有发生故障,那么其工作流程跟普通队列一样,生产者和消费者不会感知其变化,当发布消息时,依然是路由到主队列中,而主队列通过类似广播的机制,将消息扩散同步至其余从队列中,这就有点像 fanout 交换器一样。而消费者依然是从主队列中读取消息。
一旦主队列发生故障,集群就会从最老的一个从队列选举为新的主队列,这也就实现了队列的高可用了,但我们切记不要滥用这个机制,在上面也说了,队列的冗余操作会导致不能通过扩展节点增加存储空间,而且会造成性能瓶颈。
命令格式如下:
rabbitmqctl set_policy [-p Vhost] Name Pattern Definition [Priority]
参数介绍:
-p Vhost: 可选参数,针对指定vhost下的queue进行设置 Name: policy的名称 Pattern: queue的匹配模式(正则表达式) Definition: 镜像定义,包括三个部分ha-mode, ha-params, ha-sync-mode ha-mode: 指明镜像队列的模式,有效值为 all/exactly/nodes all: 表示在集群中所有的节点上进行镜像 exactly: 表示在指定个数的节点上进行镜像,节点的个数由ha-params指定 nodes: 表示在指定的节点上进行镜像,节点名称通过ha-params指定 ha-params: ha-mode模式需要用到的参数 ha-sync-mode: 进行队列中消息的同步方式,有效值为automatic和manual priority: 可选参数,policy的优先级
举个例子,声明名为ha-all
的策略,它与名称以ha
开头的队列相匹配,并将镜像配置到集群中的所有节点:
rabbitmqctl set_policy ha-all "^" '{"ha-mode":"all"}'
类似操作很多,具体使用可以参考官方 api。