RabbitMQ集群

6. RabbitMQ集群

6.1 集群形式

RabbiMQ 是用 Erlang 开发的, 集群非常方便, 因为 Erlang 天生就是一门分布式语言, 但其本身并不支持负载均衡。

RabbitMQ 集群中节点包括内存节点(RAM)、 磁盘节点(Disk, 消息持久化)集群中至少有一个 Disk 节点。

6.1.1 普通模式(默认)

对于普通模式, 集群中各节点有相同的队列结构, 但消息只会存在于集群中的一个节点。 对于消费者来说, 若消息进入 A 节点的 Queue 中, 当从 B 节点拉取时, RabbitMQ 会将消息从 A 中取出, 并经过 B 发送给消费者。

应用场景: 该模式各适合于消息无需持久化的场合, 如日志队列。 当队列非持久化, 且创建该队列的节点宕机, 客户端才可以重连集群其他节点, 并重新创建队列。 若为持久化,只能等故障节点恢复

6.1.2 镜像模式

与普通模式不同之处是消息实体会主动在镜像节点间同步, 而不是在取数据时临时拉取, 高可用; 该模式下, mirror queue 有一套选举算法, 即 1 个 master、 n 个 slaver, 生产者、 消费者的请求都会转至 master

应用场景: 可靠性要求较高场合, 如下单、 库存队列。
缺点: 若镜像队列过多, 且消息体量大, 集群内部网络带宽将会被此种同步通讯所消耗
(1) 镜像集群也是基于普通集群, 即只有先搭建普通集群, 然后才能设置镜像队列。
(2) 若消费过程中, master 挂掉, 则选举新 master, 若未来得及确认, 则可能会重复消费

6.2 搭建集群(普通模式)

6.2.1 首先创建容器映射目录

#创建rabbitmq用于存放rabbitmq集群映射信息
mkdir /mydata/rabbitmq
#分别创建各集群映射目录
cd rabbitmq/
mkdir rabbitmq01 rabbitmq02 rabbitmq03

6.2.2 启动集群镜像容器

rabbitmq01

docker run -d --hostname rabbitmq01 --name rabbitmq01 -v /mydata/rabbitmq/rabbitmq01:/var/lib/rabbitmq -p 15673:15672 -p 5673:5672 -e RABBITMQ_ERLANG_COOKIE='zr' rabbitmq:3.8.2-management

rabbitmq02

docker run -d --hostname rabbitmq02 --name rabbitmq02 -v/mydata/rabbitmq/rabbitmq02:/var/lib/rabbitmq -p 15674:15672 -p 5674:5672 -e RABBITMQ_ERLANG_COOKIE='zr' --link rabbitmq01:rabbitmq01 rabbitmq:3.8.2-management

rabbitmq03

docker run -d --hostname rabbitmq03 --name rabbitmq03 -v /mydata/rabbitmq/rabbitmq03:/var/lib/rabbitmq -p 15675:15672 -p 5675:5672 -e RABBITMQ_ERLANG_COOKIE='zr' --link rabbitmq01:rabbitmq01 --link rabbitmq02:rabbitmq02 rabbitmq:3.8.2-management

注意事项:

–hostname 设置容器的主机名

RABBITMQ_ERLANG_COOKIE 节点认证作用, 部署集成时 需要同步该值

RABBITMQ_ERLANG_COOKIE 为rabbitmq多节点之间通信所用到的cookie,rabbitmq集群就是利用这一特性实现的

启动成功后

http://192.168.157.128:15673/#/

http://192.168.157.128:15674/#/

http://192.168.157.128:15675/#/

账号:guest

密码:guest

登录查看一下,目前都是单节点

RabbitMQ集群_第1张图片

6.2.3 节点加入集群

设置rabbitmq01为主节点

docker exec -it rabbitmq01 /bin/bash
rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl start_app
Exit

RabbitMQ集群_第2张图片

如果出现以下情况说明rabbitmq版本太高了,新拉一个镜像3.8.2(老师对应的),当然也可以按照高版本的配置

docker pull rabbitmq:3.8.2

image-20220215101805732

将rabbitmq02加入rabbitmq01

docker exec -it rabbitmq02 /bin/bash
rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl join_cluster --ram rabbit@rabbitmq01
rabbitmqctl start_app
exit

RabbitMQ集群_第3张图片

将rabbitmq02加入rabbitmq01

docker exec -it rabbitmq03 bash
rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl join_cluster --ram rabbit@rabbitmq01
rabbitmqctl start_app
exit

最后能看到其他节点信息也就成功了(普通模式)

RabbitMQ集群_第4张图片

6.2.4 普通模式集群测试

说明一下端口15673为rabbitmq01 ,15674为rabbitmq02,15675为rabbitmq03

在rabbitmq01新建test队列

RabbitMQ集群_第5张图片

在rabbitmq01新建test交换机,并绑定关系

RabbitMQ集群_第6张图片

RabbitMQ集群_第7张图片

同时发现rabbitmq02,rabbitmq03中也创建了相同的交换机,队列,绑定关系

RabbitMQ集群_第8张图片

RabbitMQ集群_第9张图片

向rabbitmq01的交换机发送消息

RabbitMQ集群_第10张图片

在rabbitmq02 rabbitmq03中也能拿到消息

RabbitMQ集群_第11张图片

RabbitMQ集群_第12张图片

在一个节点中消费了该消息,其他节点中将不会存在该消息

6.3 实现镜像集群

在普通模式集群的条件下才能搭建镜像集群,并且需要选择一个主节点,此处我们选择rabbitmq01为主节点

#进入rabbitmq01容器
docker exec -it rabbitmq01 bash

首先查看此时的策略什么,发现为空,默认普通模式

rabbitmqctl list_policies -p /

image-20220215153330610

增加镜像模式策略

策略模式 all 即复制到所有节点, 包含新增节点,

策略正则表达式为 “^” 表示所有匹配所有队列名称。

“^hello”表示只匹配名为 hello 开始的队列

rabbitmqctl set_policy -p / ha "^" '{"ha-mode":"all","ha-sync-mode":"automatic"}'

查看此时的策略

image-20220215153454610

管理页面查看

RabbitMQ集群_第13张图片

RabbitMQ集群_第14张图片

再次向rabbitma01的test交换机发送信息,正常情况与普通模式一致

当我向rabbitma01发送消息后,宕机了,普通模式由于本质是其他节点比如rabbitma02去拿rabbitma01的消息再转交给我,所以当rabbitma01宕机后就拿不到消息了.

镜像模式由于是同步的,当rabbitma01宕机后客户端是直接可以向其他节点拿到消息的

(个人理解普通模式就是代理,源头断了也就什么都没有了;镜像模式就是复制cv,一个地方断掉了,但是还可以从其他地方还能拿到)

你可能感兴趣的:(rabbitmq,分布式,java)