RabbitMQ

发布于:2025-05-14 ⋅ 阅读:(14) ⋅ 点赞:(0)

目录

前言:

场景带入:

一、Queue是什么?

二、ExChange是什么?

三、RabbitMQ是什么?

四、优先级队列是什么?

五、RabbitMQ集群

5.1:普通集群模式

5.2:镜像队列集群

5.3:Quorum队列集群

结尾:


前言:

本文将深入剖析RabbitMQ的核心设计哲学,从消息路由的拓扑逻辑到集群化部署的可靠性保障,从死信队列的异常处理到镜像队列的容灾策略,结合电商秒杀、物流状态同步等典型场景,揭示消息中间件如何通过异步削峰、流量控制等机制重塑现代分布式系统的通信基因。通过本次技术探索,我们不仅能掌握RabbitMQ的工具使用,更能理解消息驱动架构对系统弹性设计带来的范式升级。


场景带入:

你是一个程序员,你维护了A,B两个服务,A服务负责转发请求到B服务,B服务是个算法服务,CPU资源有限,当大量的请求发送过来的时候,B服务压力巨大。那此时我们想要优先的转发VIP用户的请求,那么如果普通用户和VIP用户同时发送请求,那么我们该如何做到VIP优先呢?

没有什么时加一层中间层不能解决的,如果有那就再加一层。这次我们要加的中间层RabbitMQ,


一、Queue是什么?

消息队列本质上是一个类似链表的独立进程,链表里的每个节点就是一个消息,他介于生产者和消费者之间,再流量高峰时先暂存数据,再慢慢的消费数据,可以很好的保护消费者。这也就是所谓的削峰填谷。

消息又分为很多的种类:比如订单消息用户消息等,为了更好的管理这些不同种类的消息,可以提供多个队列(Queue)。

生产者可以自定义Queue的名字,并且根据需要将消息投递到不同的Queue中,每个Queue都设计为独立的进程,某个进程挂了,不会影响其他进程的使用,提高了可用性。


二、ExChange是什么?

有些生产者想要发消息给一个Queue,而有些生产者想把消息发给多个Queue甚至是广播给所有的Queue。那么这个时候我们就需要加个中间层,就是消息路由分发策略的组件,交换机Exchage。

将他与Queue绑定在一起,通过一个类似于正则表达式的字符串bindingKey声明绑定的关系,让用户根据需要选择要投递的队列。

这些绑定在Exchage里的路由方式和绑定关系,我们称作是元数据


三、RabbitMQ是什么?

像这样包含多个Queue进程和Exchage的组件的消息队列就是所谓的RabbitMQ。

每一个服务器上的RabbitMQ实例就代表一个Broker,大佬们就在这个架构的基础上为RabbitMQ实现了各种丰富的特性,比如:延时队列死信队列优先级队列等等,


四、优先级队列是什么?

生产者在发送消息时,会给消息标上优先级,那么此时消费者会优先消费优先级高的消息。

开头的问题就可以用这个来解决。VIP用户的消息优先级会更高,会先处理。我们普通用户就得慢慢等待,所以我们有时候会发现没有氪金的服务会响应慢。果然还得是钞能力啊!

此时,我们发现RabbitMQ虽然功能会很丰富,但是这玩意就是个单实例节点,有些过于简单了,高可用和高扩展是一个都没见到。那么,一个不行咋办?那就多加几个变成集群。

五、RabbitMQ集群

既然单节点存在诸多问题,那我们就让多个节点构成集群,我们可以在多个服务器上部署RabbitMQ实例,并且可以通过RabbitMQ提供的命令,将这些实例组成一个集群。RabbitMQ支持多种集群模式。

5.1:普通集群模式

在普通集群模式中,每个Broker都是一个完整功能的RabbitMQ实例,都能够进行读写,他们之间会互相同步Exchage里的元数据,但不会同步Queue数据。

假设Queue1和Queue2和Queue3分别部署在Broker1、2、3中

写操作:

生产者将消息写入到broker1中,broker1并不会把数据同步到borker2和borker3中,但是如果broker1中Exchage的数据有变化,那就会把元数据同步到borker2和borker3中。

读操作:

消费者如果读取的是broker1的数据,那就直接能读取到,返回Queue中的数据,要是读取的是broker2的数据,此时broker2就会根据Exchage中的元数据从broker1那里读取数据再返回给消费者,这样就可以通过增加broker提升RabbitMQ集群整体的吞吐量,保证了扩展性。但是问题也很明显:这并没有提升单个RabbitMQ的读写性能,而且最重要的存在单点问题:某个broker要是挂了,那就获取不到他的数据了,broker之间并不同步Queue里的数据,这样和高可用就不沾边了。

为了解决高可用的问题,就引出了镜像队列集群的方式

5.2:镜像队列集群

我们可以再普通集群模式的基础上给Queue在其他broker中加几个副本,他们有主从关系,主Queue负责读写数据。

从Queue负责同步复制主Queue数据,所以从Queue也叫镜像队列,一旦主Queue所在的Broker挂了,从Queue就可以顶上成为新的主Queue,实现高可用。

写操作:

数据写入主Queue后,会将Exchage和Queue数据同步给其他的broker上。

读操作:

消费者读取数据时,如果访问主Queue所在的broker则直接返回数据,如果访问的是从Queue,他就会访问主Queue里的数据,之后返回给消费者。

此时这种模式下的弊端也比较明显,如果数据量一大起来,那么整个系统的带宽消耗就非常大。

普通集群模式是吞吐量大,高可用低,镜像队列模式牺牲了吞吐量,成就了高可用。

还是那句话:架构做到最后都是做折中。


5.3:Quorum队列集群

你有没有想过?为什么每个节点都知道某个Queue在哪个broker中,这之间是怎么实现的呢?

他们之间肯定有个机制可以同步元数据(Exchage),但是架构中却没有一个类似kafkaZookeeper那样的中心节点,他是怎么在多个节点间同步数据的呢?

这是因为RabbitMQ是基于Erlang语言进行开发,他比较特殊的点在于:

它自带虚拟机分布式通信框架,RabbitMQ通过这个分布式通信框架在Broker间同步元数据。但是他有个问题,如果Broker之间通信断开,那么此时镜像队列会出现多个节点都认为自己的主节点(造反了属于是),导致的数据不一致,也就是所谓的脑裂问题

我们可以使用靠谱的一致性算法raft,通过引入选举机制,来解决网络分区问题,这就是所谓的Quorum队列集群。

虽然官方推荐大家使用Quorum队列集群,并且宣布镜像队列集群已被弃用,但目前大部分公司用的还是镜像队列集群,在成本和效率可控的情况下,人和系统有一个能跑就行。


结尾:

随着云原生技术的演进,RabbitMQ正在与Kubernetes Operator、Service Mesh等新范式深度融合。但无论技术形态如何变化,其承载的异步通信思想始终是分布式架构的基石。期待读者在掌握本文技术要点后,能进一步探索RabbitMQ在事件溯源、CQRS模式等前沿场景中的创新应用,让消息中间件真正成为构建弹性系统的战略级基础设施。


网站公告

今日签到

点亮在社区的每一天
去签到