文章目录
主机名 | ip | 配置 |
---|---|---|
ubuntu01 | 192.168.56.104 | CPU:单核 内存:2G 硬盘:60G |
ubuntu02 | 192.168.56.105 | CPU:单核 内存:2G 硬盘:40G |
ubuntu03 | 192.168.56.106 | CPU:单核 内存:2G 硬盘:40G |
一、 普通集群模式
1.1 普通集群模式的搭建
1.1.1 分别启动三台机器上的rabbitmq
ubuntu01:
# 下载镜像
docker pull rabbitmq:3.7-management
# 启动容器
# --name rabbitmq01 容器名rabbitmq01
# --net host 主机网络,则默认使用5672和15672端口,无需端口映射
# --hostname rabbitmq01 --add-host rabbitmq02:192.168.56.105 --add-host rabbitmq03:192.168.56.106 将三台主机的域名映射写入/etc/hosts文件
# -v v1:/var/lib/rabbitmq rabbitmq持久化
# -e RABBITMQ_ERLANG_COOKIE=rst200233 三台机器的RABBITMQ_ERLANG_COOKIE必须相同
# -e RABBITMQ_DEFAULT_USER=rst200233 -e RABBITMQ_DEFAULT_PASS=rst200233 默认的用户密码都为rst200233
docker run -itd --name rabbitmq --net host --hostname rabbitmq01 --add-host rabbitmq02:192.168.56.105 --add-host rabbitmq03:192.168.56.106 -v v1:/var/lib/rabbitmq -e RABBITMQ_ERLANG_COOKIE=rst200233 -e RABBITMQ_DEFAULT_USER=rst200233 -e RABBITMQ_DEFAULT_PASS=rst200233 rabbitmq:3.7-management
ubuntu02:
# 下载镜像
docker pull rabbitmq:3.7-management
# 启动容器
docker run -itd --name rabbitmq --net host --hostname rabbitmq02 --add-host rabbitmq01:192.168.56.104 --add-host rabbitmq03:192.168.56.106 -v v2:/var/lib/rabbitmq -e RABBITMQ_ERLANG_COOKIE=rst200233 -e RABBITMQ_DEFAULT_USER=rst200233 -e RABBITMQ_DEFAULT_PASS=rst200233 rabbitmq:3.7-management
ubuntu03:
# 下载镜像
docker pull rabbitmq:3.7-management
# 启动容器
docker run -itd --name rabbitmq --net host --hostname rabbitmq02 --add-host rabbitmq01:192.168.56.104 --add-host rabbitmq03:192.168.56.106 -v v2:/var/lib/rabbitmq -e RABBITMQ_ERLANG_COOKIE=rst200233 -e RABBITMQ_DEFAULT_USER=rst200233 -e RABBITMQ_DEFAULT_PASS=rst200233 rabbitmq:3.7-management
分别访问15672端口,输入rst200233/rst 200233看到如下页面,说明启动成功.
1.1.2 将两台slave分别加入集群
在ubuntu02和ubuntu03机器上都执行执行下列操作,作为slave加入集群
# 进入容器
docker exec -it rabbitmq /bin/bash
# 关闭应用
rabbitmqctl stop_app
# 清空队列
rabbitmqctl reset
# 加入集群
rabbitmqctl join_cluster --ram rabbit@rabbitmq01
# 启动应用
rabbitmqctl start_app
执行完毕后,在任一机器的15672端口查看,均可以看到三个节点
1.2 普通集群模式的特点
-
消息可能存在任意的一个节点之中.
细心的人可能会发现在slave加入节点的时候,指定了**–ram**参数,表示这两个slave节点都是内存节点.
从下图从也可以看出有一个磁盘节点和两个内存节点。
但是有人就错误的认为消息都存在了磁盘节点,内存节点并不会存消息,而是从磁盘节点传输过来的,这是错误的。
从下图中也可以看出每个节点上都存在一个队列。
磁盘节点和内存节点的区别在于: 磁盘节点除了内存中会存运行时状态信息(队列信息,集群信息,用户信息等),磁盘中也会存运行时状态信息。消息的持久化只与delivery-mode有关,不管是磁盘节点还是内存节点,只要delivery-mode标记为2,这条消息就会写入磁盘. -
访问任一节点,能对其它节点的队列写入或者读取消息.
虽然队列只会存在任意的一个节点之中,但是各个节点的元数据会进行同步,所以我们能够在任一节点中看到所有的队列信息。但我们生产或者消费的队列不在连接的节点上时,则会根据元数据信息将消息进行转发。 -
普通集群模式不具备高可用
由于普通集群模式只同步了各个节点的元数据(队列名,路由器等信息),并没有在每个节点上创建相同的队列,所以当某个节点down掉后,该节点上创建的队列都不可用了。
二、 镜像集群模式
2.1 普通集群模式的搭建
之前说过普通集群模式只同步了元数据,队列实际只存在于某一节点,并不具备高可用。而镜像集群模式则是每个节点上都会创建一个相同的队列,实现高可用。
镜像集群模式是在普通集群模式的基础上,指定策略就行了。(so easy 😄)
在集群内的任一机器指定策略
# 进入容器
docker exec -it rabbitmq /bin/bash
# 指定同步策略,自动同步所有的节点和队列
# 也可灵活的同步部分节点和队列 https://blog.csdn.net/weixin_40816738/article/details/105918592
rabbitmqctl set_policy ha-all "^" '{"ha-mode":"all","ha-sync-mode":"automatic"}'
执行完成后会发现,每个节点的队列上都有了 +2 的标志,代表还有两个该队列的副本。
三、 集群的使用
- 查看集群状态
# 或者直接通过15672端口的web网页查看更为方便
rabbitmqctl cluster_status
- 将从节点从集群中剔除
# 在主节点上执行剔除命令
rabbitmqctl -n rabbit@rabbitmq01 forget_cluster_node rabbit@rabbitmq02
- 重新加入集群时报错
Error: {:inconsistent_cluster, 'Node rabbit@rabbitmq01 thinks it\'s clustered with node rabbit@rabbitmq02, but rabbit@rabbitmq02 disagrees'}
重新加入集群的节点中残留有旧的信息,先清空旧的信息,再加入集群
rabbitmqctl reset
rabbitmqctl join_cluster --ram rabbit@rabbitmq01
rabbitmqctl start_app
- 集群恢复
停掉集群中的一台机器,然后再重启这台机器,发现并未自动的加入到集群中,原因是出现了网络分区现象。
解决办法: 修改/etc/rabbitmq/rabbitmq.conf文件,配置cluster_partition_handling为autoheal
RabbitMQ Network Partitions 处理策略
cluster_partition_handling = autoheal