Docker搭建RabbitMQ集群

导读:本篇文章讲解 Docker搭建RabbitMQ集群,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

1、集群分类

RabbitMQ的是基于Erlang语言编写,而Erlang又是一个面向并发的语言,天然支持集群模式。RabbitMQ的集群以下分类:

  • 标准集群:是一种分布式集群,将队列分散到集群的各个节点,从而提高整个集群的并发能力。
  • 镜像集群:是一种主从集群,标准集群的基础上,添加了主从备份功能(非强一致性),提高集群的数据可用性。
  • 仲裁队列: 是3.8版本以后才有的新功能,用来替代镜像集群,也是一种主从集群,主从同步基于Raft协议,强一致。

镜像集群虽然支持主从,但主从同步并不是强一致的,某些情况下可能有数据丢失的风险。因此在RabbitMQ的3.8版本以后,推出了新的功能:仲裁队列来代替镜像集群,底层采用Raft协议确保主从的数据一致性。

1.1、标准集群

  • 标准模式集群不进行数据同步。
  • 会在集群的各个节点间共享部分数据,包括:交换机、队列元信息。不包含队列中的消息。
  • 当访问集群某节点时,如果队列不在该节点,会从数据所在节点传递到当前节点并返回。
  • 队列所在节点宕机,队列中的消息就会丢失。
  • 比如:我们有2个MQ:mq1和mq2,如果你的消息在mq1,而你连接到了mq2,那么mq2会去mq1拉取消息,然后返回给你。如果mq1宕机,消息就会丢失。

结构如图:
在这里插入图片描述

1.2、镜像集群

镜像集群:本质是主从模式,具备下面的特征:

  • 交换机、队列、队列中的消息会在各个mq的镜像节点之间同步备份。
  • 创建队列的节点被称为该队列的主节点, 备份到的其它节点叫做该队列的镜像节点。
  • 一个队列的主节点可能是另一个队列的镜像节点。
  • 所有操作都是主节点完成,然后同步给镜像节点。
  • 主节点宕机后,镜像节点会替代成新的主节点。

结构如图:
在这里插入图片描述

1.3、仲裁队列

​ 仲裁队列是3.8版本以后才有的新功能,用来替代镜像队列,具备下列特征:

  • 与镜像队列一样,都是主从模式,支持主从数据同步
  • 使用非常简单,没有复杂的配置
  • 主从同步基于Raft协议,强一致

2、集群部署

2.1、节点说明

在rabbitmq集群部署时,集群中的节点标示默认都是:rabbit@[hostname]

计划部署3节点的mq集群,,三个节点在不同机器上,为了方便主机名称分别为mq1、mq2、mq3,节点也进行相应的映射;
15672映射为8081 、8082 、8083,5672映射为8071、8072、8073;如下:

主机名 节点标识 控制台端口amqp通信端口 amqp通信端口 Ip地址
mq1 rabbit@mq1 8081 8071 111.229.160.173
mq2 rabbit@mq2 8082 8072 111.229.160.174
mq3 rabbit@mq3 8083 8073 111.229.160.175

放了方便延时,以下部署都在同一台服务器中进行,因为端口都做了映射不会出现冲突

2.2、标准集群模式

2.2.1.创建目录

mkdir -p /root/docker/rabbitmq-cluster/mq1[2|3]

2.2.2.设置hosts

注意:如果是同一台机器上,搭建不同的docker实例,则不进行设置。

分别在三台不同的机器上编辑hosts文件

# mq1
vim  /root/docker/rabbitmq-cluster/mq1/hosts
# mq2
vim  /root/docker/rabbitmq-cluster/mq2/hosts
# mq3
vim  /root/docker/rabbitmq-cluster/mq3/hosts

内容都如下:

# 配置hosts映射
111.229.160.173   mq1
111.229.160.174   mq2
111.229.160.175   mq3

2.2.3.设置cookie:

RabbitMQ底层依赖于Erlang,而Erlang虚拟机就是一个面向分布式的语言,默认就支持集群模式。集群模式中的每个RabbitMQ 节点使用 cookie 来确定它们是否被允许相互通信。

要使两个节点能够通信,它们必须具有相同的共享密钥,称为Erlang cookie,cookie 是一串最多 255 个字符的任意字母数字字符。

每个集群节点必须具有相同的 cookie,实例之间也需要它来相互通信。

# Cookie配置
vim /root/docker/rabbitmq-cluster/mq1/.erlang.cookie

# 配置内容-cookie值(任意值)
UDCUIBNPHPETOIURAHRF

# 修改cookie文件的权限
chmod 600 /root/docker/rabbitmq-cluster/mq1/.erlang.cookie

2.2.4、设置配置文件

# mq1
vim /root/docker/rabbitmq-cluster/mq1/rabbitmq.conf

内容都如下:

# 配置内容
loopback_users.guest = false
listeners.tcp.default = 5672
cluster_formation.peer_discovery_backend = rabbit_peer_discovery_classic_config
cluster_formation.classic_config.nodes.1 = rabbit@mq1
cluster_formation.classic_config.nodes.2 = rabbit@mq2
cluster_formation.classic_config.nodes.3 = rabbit@mq3

注意rabbit@xxx为每个rabbitmq实例的hostname,和启动容器时的--hostname值一致

2.2.5、拷贝目录

如果有多台服务器,则将配置好的一个rabbitmq节点的文件,拷贝到其他服务器上;如果是一台服务器,则拷贝到不同的目录下即可。

# 将mq1目录拷贝为mq2、mq3
cp /root/docker/rabbitmq-cluster/mq1 /root/docker/rabbitmq-cluster/mq2 -r

cp /root/docker/rabbitmq-cluster/mq1 /root/docker/rabbitmq-cluster/mq3 -r

2.2.6、启动容器

注意:如果如果是同一台机器上,搭建不同的docker实例,则直接创建同一个网络环境

#创建网络
docker network create mq-net

模板如下:

docker run -d \
# 如果是同一台机器则需要指定net
--net mq-net \
# 如果是不同机器,则需要挂载hosts文件,如果是同一台机器则不配做hosts挂载
-v /root/docker/rabbitmq-cluster/xxx/hosts:/etc/hosts \
-v /root/docker/rabbitmq-cluster/xxx/rabbitmq.conf:/etc/rabbitmq/rabbitmq.conf \
-v /root/docker/rabbitmq-cluster/xxx/.erlang.cookie:/var/lib/rabbitmq/.erlang.cookie \
-e RABBITMQ_DEFAULT_USER=xxx\
-e RABBITMQ_DEFAULT_PASS=xxx\
--name xxx \
--hostname xxx \
-p xxxx:5672 \
-p xxxx:15672 \
rabbitmq:3.8.27-management

本次搭建,在同一台服务器上完成,所以需要指定net,不需要挂载hosts文件

启动mq1:

docker run -d \
--net mq-net \
-v /root/docker/rabbitmq-cluster/mq1/rabbitmq.conf:/etc/rabbitmq/rabbitmq.conf \
-v /root/docker/rabbitmq-cluster/mq1/.erlang.cookie:/var/lib/rabbitmq/.erlang.cookie \
-e RABBITMQ_DEFAULT_USER=admin \
-e RABBITMQ_DEFAULT_PASS=admin \
--name mq1 \
--hostname mq1 \
-p 8071:5672 \
-p 8081:15672 \
rabbitmq:3.8.27-management

启动mq2:

docker run -d \
--net mq-net \
-v /root/docker/rabbitmq-cluster/mq2/rabbitmq.conf:/etc/rabbitmq/rabbitmq.conf \
-v /root/docker/rabbitmq-cluster/mq2/.erlang.cookie:/var/lib/rabbitmq/.erlang.cookie \
-e RABBITMQ_DEFAULT_USER=admin \
-e RABBITMQ_DEFAULT_PASS=admin \
--name mq2 \
--hostname mq2 \
-p 8072:5672 \
-p 8082:15672 \
rabbitmq:3.8.27-management

启动mq3:

docker run -d \
--net mq-net \
-v /root/docker/rabbitmq-cluster/mq3/rabbitmq.conf:/etc/rabbitmq/rabbitmq.conf \
-v /root/docker/rabbitmq-cluster/mq3/.erlang.cookie:/var/lib/rabbitmq/.erlang.cookie \
-e RABBITMQ_DEFAULT_USER=admin \
-e RABBITMQ_DEFAULT_PASS=admin \
--name mq3 \
--hostname mq3 \
-p 8073:5672 \
-p 8083:15672 \
rabbitmq:3.8.27-management

结果:
在这里插入图片描述

2.2.7、集群测试

控制台管理地址:http://xxx.xxx.xxx.xxx:8081|8082|8083,访问任意节点,所看到的信息是一致的;
为了更加方便的管理,可以通过nginx配置负载均衡,实现web页面的统一访问地址。
在这里插入图片描述

2.2.7.1.连通性测试

在mq1这个节点上添加一个队列:
在这里插入图片描述
分别访问mq2和mq3两个控制台也都能看到:
在这里插入图片描述

2.2.7.2.数据共享测试

进入mq1节点发送一台消息:
在这里插入图片描述
在这里插入图片描述
分别访问mq2和mq3两个控制台也能看到消息:
在这里插入图片描述

2.2.7.3.可用性测试

让节点mq1宕机:

docker stop mq1

分别访问mq2和mq3两个控制台,看到simple.mq1已不可用:
在这里插入图片描述
说明mq1的数据并没有拷贝到mq2和mq3。

2.3、镜像集群模式

在标准集群模式下,一旦创建队列的主机宕机,队列就会不可用。不具备高可用能力。如果要解决这个问题,必须使用镜像集群方案

镜像模式下,创建队列的节点被称为该队列的主节点,队列还会拷贝到集群中的其它节点,也叫做该队列的镜像节点。

队列的所有操作都在主节点上完成,镜像节点仅仅起到备份数据作用。如果是从节点接收到操作请求,也会路由到主节点去完成。
当主节点接收到消费者的ACK时,所有镜像都会删除节点中的数据。

镜像模式的配置有3种模式:

ha-mode ha-params 效果
exactly count 集群中队列副本(主服务器和镜像服务器之和)的数量。count如果为1意味着单个副本:即队列主节点。count值为2表示2个副本:1个队列主和1个队列镜像。换句话说:count = 镜像数量 + 1。如果群集中的节点数少于count,则该队列将镜像到所有节点。如果有集群总数大于count+1,并且包含镜像的节点出现故障,则将在另一个节点上创建一个新的镜像。推荐使用exactly,设置副本数为(N / 2 +1)。
all (none) 队列在群集中的所有节点之间进行镜像。队列将镜像到任何新加入的节点。镜像到所有节点将对所有群集节点施加额外的压力,包括网络I / O,磁盘I / O和磁盘空间使用情况。
nodes node names 指定队列创建到哪些节点,如果指定的节点全部不存在,则会出现异常。如果指定的节点在集群中存在,但是暂时不可用,会创建节点到当前客户端连接到的节点。

镜像集群模式是对队列的一种主从复制操作,需要通过一定规则对指定的队列实现主从同步操作

2.3.1、exactly模式

rabbitmqctl set_policy ha-exactly "^exactly\." '{"ha-mode":"exactly","ha-params":2,"ha-sync-mode":"automatic"}'
  • rabbitmqctl set_policy:固定写法
  • ha-exactly:策略名称,自定义
  • "^exactly\.":匹配队列的正则表达式,符合命名规则的队列才生效,这里是任何以lhz.开头的队列名称
  • '{"ha-mode":"exactly","ha-params":2,"ha-sync-mode":"automatic"}': 策略内容
    • "ha-mode":"exactly":策略模式,此处是exactly模式,指定副本数量
    • "ha-params":2:策略参数,这里是2,就是副本数量为2,1主1镜像
    • "ha-sync-mode":"automatic":同步策略,默认是manual,即新加入的镜像节点不会同步旧的消息。如果设置为automatic,则新加入的镜像节点会把主节点中所有消息都同步,会带来额外的网络开销

2.3.2、all模式

rabbitmqctl set_policy ha-all "^all\." '{"ha-mode":"all"}'
  • ha-all:策略名称,自定义
  • "^all\.":匹配所有以all.开头的队列名
  • '{"ha-mode":"all"}':策略内容
    • "ha-mode":"all":策略模式,此处是all模式,即所有节点都会称为镜像节点

2.3.3、nodes模式

rabbitmqctl set_policy ha-nodes "^nodes\." '{"ha-mode":"nodes","ha-params":["rabbit@nodeA", "rabbit@nodeB"]}'
  • rabbitmqctl set_policy:固定写法
  • ha-nodes:策略名称,自定义
  • "^nodes\.":匹配队列的正则表达式,符合命名规则的队列才生效,这里是任何以nodes.开头的队列名称
  • '{"ha-mode":"nodes","ha-params":["rabbit@nodeA", "rabbit@nodeB"]}': 策略内容
    • "ha-mode":"nodes":策略模式,此处是nodes模式
    • "ha-params":["rabbit@mq1", "rabbit@mq2"]:策略参数,这里指定副本所在节点名称

2.3.4、测试

使用exactly,设置镜像数为(N / 2 +1)。

使用exactly模式的镜像,因为集群节点数量为3,因此镜像数量就设置为2.

对任意节点操作,被操作的节点会视为主节点

创建命令:

docker exec -it mq1 rabbitmqctl set_policy exactly-test "^test\." '{"ha-mode":"exactly","ha-params":2,"ha-sync-mode":"automatic"}'
  • exactly-test:模式名称
  • “^test.”:正则匹配,test开头的队列

2.3.4.1、连通性测试

在mq1节点,创建队列:test.mq1
在这里插入图片描述

在任意一个mq控制台查看队列:
在这里插入图片描述

2.3.4.2、数据共享测试

通过test.queue发送一条消息:
在这里插入图片描述

然后在任意节点控制台查看消息:
在这里插入图片描述

2.3.4.3、高可用测试

test.queue队列所在的节点mq1宕机

docker stop mq1

查看集群状态:
在这里插入图片描述
查看队列状态:
在这里插入图片描述
发现test.queue队列,依然是健康的!并且其主节点切换到了rabbit@mq3上

2.4、仲裁队列模式

在任意控制台添加一个队列,一定要选择队列类型为Quorum类型
在这里插入图片描述
在任意控制台查看队列:
在这里插入图片描述
可以看到,仲裁队列的 + 2字样,代表这个队列有2个镜像节点

3、集群扩容

启动一个新的MQ容器:

# 拷贝目录
cp /root/docker/rabbitmq-cluster/mq1 /root/docker/rabbitmq-cluster/mq4 -r

# 启动容器
docker run -d \
--net mq-net \
-v /root/docker/rabbitmq-cluster/mq4/rabbitmq.conf:/etc/rabbitmq/rabbitmq.conf \
-v /root/docker/rabbitmq-cluster/mq4/.erlang.cookie:/var/lib/rabbitmq/.erlang.cookie \
-e RABBITMQ_DEFAULT_USER=admin \
-e RABBITMQ_DEFAULT_PASS=admin \
--name mq4 \
--hostname mq4 \
-p 8074:5672 \
-p 8084:15672 \
rabbitmq:3.8.27-management

进入容器控制台:

docker exec -it mq4 bash

停止mq进程:

rabbitmqctl stop_app

重置RabbitMQ中的数据:

rabbitmqctl reset

mq4加入mq1:

rabbitmqctl join_cluster rabbit@mq1

再次启动mq进程:

rabbitmqctl start_app

在这里插入图片描述

4、SprngBoot集群配置

spring:
  application:
    name: rabbit
  # rabbitmq配置
  rabbitmq:
    # 集群配置
    addresses: 127.0.0.1:8071, 127.0.0.1:8072, 127.0.0.1:8073
    username: admin
    password: admin
    virtual-host: /

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/18137.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!