应用做集群,需要面对数据同步和通信的问题。因为Erlang天生具备分布式的特性,所以RabbitMQ天然支持集群,不需要通过引入ZK或者数据库来实现数据同步
RabbitMQ通过
/var/lib/rabbitmq/.erlang.cookie来验证身份,需要在所有节点上保持一致。
集群通过25672端口两两通信,需要开放防火墙的端口。需要注意的是,RabbitMQ 集群无法搭建在广域网上,除非使用 federation 或者shovel等插件(没这个必要,在同一个机房做集群)。
集群的配置步骤:
-
配置hosts
-
同步erlang.cookie
-
加入集群(join cluster)
2.RabbitMQ 集群节点类型
=================
集群有两种节点类型,一种是磁盘节点(Disc Node),一种是内存节点(RAMNode)
2.1 磁盘节点
========
磁盘节点:将元数据(包括队列名字属性、交换机的类型名字属性、绑定、vhost)放在磁盘中
2.2 内存节点
========
内存节点:将元数据放在内存中。
PS:内存节点会将磁盘节点的地址存放在磁盘(不然重启后就没有办法同步数据了)。如果是持久化的消息,会同时存放在内存和磁盘。集群中至少需要一个磁盘节点用来持久化元数据,否则全部内存节点崩溃时,就无从同步元数据。未指定类型的情况下,默认为磁盘节点。我们一般把应用连接到内存节点(读写快),磁盘节点用来备份。
3.RabbitMQ 集群模式
===============
3.1 普通集群
========
普通集群模式下,不同的节点之间只会相互同步元数据,不同步具体的消息,若需要具体消息时需要转发到源节点(1)
为什么不直接把队列的内容(消息)在所有节点上复制一份?
主要是出于存储和同步数据的网络开销的考虑,如果所有节点都存储相同的数据,就无法达到线性地增加性能和存储容量的目的(堆机器)。
-
假如生产者连接的是节点3,要将消息通过交换机A路由到队列1,最终消息还是会转发到节点1上存储,因为队列1的内容只在节点1上。
-
同理,如果消费者连接是节点 2,要从队列 1上拉取消息,消息会从节点1 转发到节点2。其它节点起到一个路由的作用,类似于指针。
普通集群模式不能保证队列的高可用性,因为队列内容不会复制。如果节点失效将导致相关队列不可用,因此我们需要第二种集群模式。
3.2 镜像集群
========
第二种集群模式叫做镜像队列。
镜像队列模式下,消息内容会在镜像节点间同步,可用性更高。不过也有一定的副作用,系统性能会降低,节点过多的情况下同步的代价比较大。
操作方式 | 命令或步骤 |
rabbitmqctl (Windows) | rabbitmqctl set_policy ha-all “^ha.” “{”“ha-mode”":"“all”"}" |
HTTP API | PUT /api/policies/%2f/ha-all {“pattern”:"^ha.", “definition”:{“ha-mode”:“all”}} |
WebUI | 1、 avigate to Admin > Policies > Add / update a policy |
4.负载均衡 + 高可用
============
4.1 基于负载均衡组件
============
集群搭建成功后,如果有多个内存节点,那么生产者和消费者应该连接到哪个内存节点?如果在我们的代码中根据一定的策略来选择要使用的服务器,那每个地方都要修改,客户端的代码就会出现很多的重复,修改起来也比较麻烦。
最后
这份清华大牛整理的进大厂必备的redis视频、面试题和技术文档
祝大家早日进入大厂,拿到满意的薪资和职级~~~加油!!
感谢大家的支持!!
找小编(vip1024c)领取
份清华大牛整理的进大厂必备的redis视频、面试题和技术文档**
祝大家早日进入大厂,拿到满意的薪资和职级~~~加油!!
感谢大家的支持!!
[外链图片转存中…(img-tpRGByYD-1721722399147)]
找小编(vip1024c)领取