微服务框架
【SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈课程|黑马程序员Java微服务】
服务异步通讯
文章目录
- 微服务框架
- 服务异步通讯
- 53 MQ 集群
- 53.1 集群分类
- 53.1.1 集群分类
- 53.2 普通集群
- 53.2.1 普通集群
- 53.2.2 搭建普通 集群
53 MQ 集群
53.1 集群分类
53.1.1 集群分类
RabbitMQ的是基于Erlang语言编写,而Erlang又是一个面向并发的语言,天然支持集群模式。
RabbitMQ的集群有两种模式:
-
普通集群:是一种分布式集群,将队列分散到集群的各个节点,从而提高整个集群的并发能力。
-
镜像集群:是一种主从集群,普通集群的基础上,添加了主从备份功能,提高集群的数据可用性。
镜像集群虽然支持主从,但主从同步并不是强一致的【存在一定延迟】,某些情况下可能有数据丢失的风险。
因此在RabbitMQ的3.8版本以后,推出了新的功能:仲裁队列来代替镜像集群,底层采用Raft协议确保主从的数据一致性。
53.2 普通集群
53.2.1 普通集群
普通集群,或者叫标准集群(classic cluster),具备下列特征:
- 会在集群的各个节点间共享部分数据,包括:交换机、队列元信息【队列的描述信息(反正不包含消息本身)】。不包含队列中的消息。
【举个栗子】
现在有三台 RabbitMQ
现在创建了一个交换机,它可以在各个MQ 上共享
现在创建了一个 test.queue1 的队列,在第一个节点上
那就只有第一个 节点有
同理,另外还有两个 队列
虽然没有消息,但是有队列的“元信息”
在另外两个节点上可以有q1 的名字、在哪儿 等信息
- 当访问集群某节点时,如果队列不在该节点,会从数据所在节点传递到当前节点并返回
现在有个消费者
绑定了q1
但是它在访问的时候不小心 访问到了 第三个节点
但是在第三个 节点上没有q1,但是它有q1 的元信息,就是说q3 知道 q1 在哪儿
在消费者获取数据时,它就会帮助消费者 找到真正的q1
拿到数据后,从q3 返回
- 队列所在节点宕机,队列中的消息就会丢失
比如说 现在的第一个节点挂了
因为q1 在第一个节点上,
队列也会跟着 就没了,现在消费者再来,就拿不到了,这就是普通集群
53.2.2 搭建普通 集群
【课前资料,永远滴神!!!!!!】
【集群分类】
在RabbitMQ的官方文档中,讲述了两种集群的配置方式:
- 普通模式:普通模式集群不进行数据同步,每个MQ都有自己的队列、数据信息(其它元数据信息如交换机等会同步)。例如我们有2个MQ:mq1,和mq2,如果你的消息在mq1,而你连接到了mq2,那么mq2会去mq1拉取消息,然后返回给你。如果mq1宕机,消息就会丢失。
- 镜像模式:与普通模式不同,队列会在各个mq的镜像节点之间同步,因此你连接到任何一个镜像节点,均可获取到消息。而且如果一个节点宕机,并不会导致数据丢失。不过,这种方式增加了数据同步的带宽消耗。
我们先来看普通模式集群,我们的计划部署3节点的mq集群:
主机名 | 控制台端口 | amqp通信端口 |
---|---|---|
mq1 | 8081 —> 15672 | 8071 —> 5672 |
mq2 | 8082 —> 15672 | 8072 —> 5672 |
mq3 | 8083 —> 15672 | 8073 —> 5672 |
集群中的节点标示默认都是:rabbit@[hostname]
,因此以上三个节点的名称分别为:
- rabbit@mq1
- rabbit@mq2
- rabbit@mq3
【获取cookie】
RabbitMQ底层依赖于Erlang,而Erlang虚拟机就是一个面向分布式的语言,默认就支持集群模式。集群模式中的每个RabbitMQ 节点使用 cookie 来确定它们是否被允许相互通信。
要使两个节点能够通信,它们必须具有相同的共享秘密,称为Erlang cookie。cookie 只是一串最多 255 个字符的字母数字字符。
每个集群节点必须具有相同的 cookie。实例之间也需要它来相互通信。
我们先在之前启动的mq容器中获取一个cookie值,作为集群的cookie。执行下面的命令:
docker exec -it mq cat /var/lib/rabbitmq/.erlang.cookie
可以看到cookie值如下:
FXZMCVGLBIXZCDEMMVZQ
笔者的是 HULXWPIGGMYCNKDSPZAM
接下来,停止并删除当前的mq容器,我们重新搭建集群。
docker rm -f mq
OK
再清理一下数据卷 docker volume prune
OK
【准备集群配置】
在/tmp目录新建一个配置文件 rabbitmq.conf:
cd /tmp
# 创建文件
touch 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
OK
再创建一个文件,记录cookie
cd /tmp
# 创建cookie文件
touch .erlang.cookie
# 写入cookie
echo "HULXWPIGGMYCNKDSPZAM" > .erlang.cookie
# 修改cookie文件的权限
chmod 600 .erlang.cookie
OK
准备三个目录,mq1、mq2、mq3:
cd /tmp
# 创建目录
mkdir mq1 mq2 mq3
然后拷贝rabbitmq.conf、cookie文件到mq1、mq2、mq3:
# 进入/tmp
cd /tmp
# 拷贝
cp rabbitmq.conf mq1
cp rabbitmq.conf mq2
cp rabbitmq.conf mq3
cp .erlang.cookie mq1
cp .erlang.cookie mq2
cp .erlang.cookie mq3
【启动集群】
创建一个网络:
docker network create mq-net
运行命令
docker run -d --net mq-net \
-v ${PWD}/mq1/rabbitmq.conf:/etc/rabbitmq/rabbitmq.conf \
-v ${PWD}/.erlang.cookie:/var/lib/rabbitmq/.erlang.cookie \
-e RABBITMQ_DEFAULT_USER=itcast \
-e RABBITMQ_DEFAULT_PASS=123321 \
--name mq1 \
--hostname mq1 \
-p 8071:5672 \
-p 8081:15672 \
rabbitmq:3.8-management
docker run -d --net mq-net \
-v ${PWD}/mq2/rabbitmq.conf:/etc/rabbitmq/rabbitmq.conf \
-v ${PWD}/.erlang.cookie:/var/lib/rabbitmq/.erlang.cookie \
-e RABBITMQ_DEFAULT_USER=itcast \
-e RABBITMQ_DEFAULT_PASS=123321 \
--name mq2 \
--hostname mq2 \
-p 8072:5672 \
-p 8082:15672 \
rabbitmq:3.8-management
docker run -d --net mq-net \
-v ${PWD}/mq3/rabbitmq.conf:/etc/rabbitmq/rabbitmq.conf \
-v ${PWD}/.erlang.cookie:/var/lib/rabbitmq/.erlang.cookie \
-e RABBITMQ_DEFAULT_USER=itcast \
-e RABBITMQ_DEFAULT_PASS=123321 \
--name mq3 \
--hostname mq3 \
-p 8073:5672 \
-p 8083:15672 \
rabbitmq:3.8-management
笔者在启动时,遇到特多问题,最主要的就是一个权限问题,说什么不能写入配置,笔者换成3.9 的RabbitMQ ,然后把配置文件的第一行删掉才启动成功 了
OK了
随便访问一个 ,试试8081
没问题
试试8082 和 8083
没毛病
但是我下面和老师不一样,它没有检测到 8083
啊这,感觉还是不行
笔者又重新启动了 一次,OK,仨都有了
【测试】
在mq1 这个节点上新建一个队列
直接创建
OK,创建完成
现在我直接切到 8082
没毛病
看看 8083
也没问题,这就是我们之前说 的【可以看到】
现在在 8081 上写点儿数据,直接发个消息到队列 里
等下
OK,mq1 节点上有了
看看另外两个节点
OK, 没毛病,能看到, 而且能拿到,虽然仅仅是 引用,但是取的时候可以 传过来 。
现在把MQ1 节点停掉 docker stop mq1
回到8082 的控制台
现在就是一个down 的状态 了
8083 直接啥也看不到了
重新启动mq1 docker start mq1
回到浏览器
OK,这样就恢复了 【这就是普通集群】