[TOC] #### 1. 前言 --- 上一讲我们知道了单机部署的风险,也知道了需要用集群来解决 那我们就多部署几台 RabbitMQ,把它们连在一起,这就是 “普通集群” #### 2. 普通集群 --- 假设你有三台服务器: + 节点 A(192.168.1.101) + 节点 B(192.168.1.102) + 节点 C(192.168.1.103) 把它们组成一个集群,共享同一个集群名称 Producer 可以连接到任意一个节点发送消息,Consumer 可以连接到任意一个节点消费消息 看起来很美好,对吧 ? 但有一个关键细节:在普通集群下,队列的数据只存在于声明它的那个节点上 假设你在节点 A 上声明了一个队列 order_queue,那 order_queue 的数据只在节点 A 上 节点 B 和节点 C 知道这个队列存在,但它们不存数据 当你从节点 B 消费 order_queue 的消息时:节点 B 会去节点 A 上取数据,然后转发给你 相当于节点 B 充当了一个「代理」的角色,这意味着什么 ? 好的方面: + Producer 和 Consumer 可以连接任意节点,不用都挤在同一台机器上 + 连接分散了,单机压力小了 + 集群管理方便,节点之间自动同步元数据 不好的方面: + 队列数据只在一个节点上,那个节点挂了,队列就不可用了 + 跨节点取数据有网络开销,性能不如直接读本地 + 存储容量没有增加,瓶颈还是在单个节点上 #### 3. 注意事项 --- 一个容易踩坑的场景,假设: + Producer 连接节点 B + Consumer 连接节点 C + order_queue 创建在节点 A Producer 发消息,Consumer 消费消息,平时一切正常,看起来三台机器都在工作 但某一天,节点 A 宕机了,这时候你会发现: 虽然节点 B 和节点 C 还活着,Producer 还能连,Consumer 还能连,但 order_queue 已经无法提供服务 因为队列数据一直存放在节点 A 上,节点 B 和节点 C 只有队列信息,没有队列数据 很多新人第一次搭 RabbitMQ 集群时都会误以为:三台机器 = 三份数据 实际上普通集群不是这样工作的,这也是为什么:普通集群解决的是连接分散问题,不是高可用问题 普通集群 ≠ 高可用,这是很多新人最容易误解的地方 以为搭了集群就是高可用了,其实并不是 普通集群解决的是 “连接分散” 的问题,它没有解决 “数据冗余” 的问题 | | 普通集群 | 真正的高可用 | | ------------ | ------------ | ------------ | | 连接分散 | ✅ | ✅ | | 数据冗余 | ❌ | ✅ | | 节点宕机队列可用 | ❌ | ✅ | 如果队列所在的节点挂了,队列就不可用了,这和单机挂了本质上是一样的 那怎么办 ? 既然普通集群不能解决队列节点宕机的问题,我们需要一种方式,让队列的数据在多个节点上都有备份 这样即使一个节点挂了,其它节点上还有数据,队列还能继续使用,这就需要 “镜像队列”,下一讲我们来聊 #### 4. 本文小结 --- 普通集群的核心: + 多个节点组成一个集群,共享元数据 + Producer 和 Consumer 可以连接任意节点 + 但队列数据只存在于声明它的那个节点上 普通集群解决的问题:连接分散,减轻单机压力 普通集群没有解决的问题: + 队列数据没有冗余 + 节点挂了,队列不可用 记住一句话:普通集群是 “能用”,不是 “高可用”,下一讲,我们来聊镜像队列 —— 让队列数据在多个节点上都有备份