首页 > 其他分享 >【RabbitMQ】图解

【RabbitMQ】图解

时间:2025-01-17 20:32:38浏览次数:1  
标签:优先级 队列 RabbitMQ Queue 集群 图解 数据

你是一个程序员,假设你维护了两个服务 A 和 B。

A 服务负责转发用户请求到 B 服务,B 服务是个算法服务,GPU 资源有限,当请求量大到 B 服务处理不过来的时候,希望能优先处理会员用户的请求。

那么问题就来了,如果普通用户和会员用户同时发起请求,怎样才能做到会员优先呢?

好办,没有什么是加一层中间层不能解决的,如果有,那就再加一层。

这次我们要加的中间层是 消息队列 RabbitMQ

我们先来看下 RabbitMQ 里的核心概念,Queue。

一、Queue 是什么

我们知道,消息队列本质上就是一个类似链表的独立进程。链表里的每个节点是一个消息。

【图】队列是类似链表的独立进程

它介于生产者消费者之间,在流量高峰时先暂存数据,再慢慢消费数据,可以很好的保护消费者,也就是所谓的削峰填谷

【图】削峰填谷

这个类似链表的进程,就是Queue,也叫队列

但消息也分很多种类,比如订单消息和用户消息属于两类,为了更好地管理不同种类的数据, 可以提供多个 队列,生产者可以自定义 Queue 的名字,并且根据需要将消息投递到不同的 Queue 中。每个 Queue 都设计为独立的进程,某个进程挂了,不影响其他进程正常工作。

【图】A进程挂了不影响其他进程

二、Exchange 是什么

有些生产者想将消息发到一个 Queue 中,有些则是发给多个queue,甚至广播给所有 Queue ,于是 我们还需要一个可以定制消息路由分发策略的组件,交换器Exchange,将它与 Queue 绑定在一起,通过一个类似正则表达式的字符串 bindingKey声明绑定的关系,让用户根据需要选择要投递的队列。

【图】Exchange是什么

这些维护在 Exchange 里的路由方式和绑定关系,我们称为元数据

【图】元数据是什么

三、RabbitMQ 是什么

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

每一台服务器上的 RabbitMQ 实例,就代表一个 Broker。

【图】RabbitMQ是什么

大佬们在这个架构的基础上,为 RabbitMQ 实现了各种丰富的特性,你能想到的 MQ 功能它基本都实现了,比如延时队列死信队列优先级队列等等。

【图】RabbitMQ的功能

前两者跟 RocketMQ 的一样,在之前的视频里有提到过。这里重点看下优先级队列是什么。

三、优先级队列是什么

RabbitMQ 支持在生产者发送消息的时候,为消息标记上优先级,消费者总是消费优先级高的消息。

【图】优先级队列是什么

视频开头的问题,就可以通过优先级队列来完成。我们可以在 A 服务,根据用户会员等级,为消息打上对应的优先级,再投递到 RabbitMQ 中,B 服务永远优先消费高优消息,当高优消息处理完后再处理普通消息。

【图】优先级队列的应用1

这个功能非常有用,现在到处都是 AI,恨不得将一块 GPU 掰成 10 块用,比如某聊天 AI,当服务遭到大量访问时,免费用户会感觉很慢甚至报错,但会员用户依旧响应丝滑。

【图】优先级队列的应用

到这里,大家估计也发现了,虽然 RabbitMQ 功能很丰富,但它的架构就是个单实例节点,有些过于简单了,像什么高可用高扩展,那是一个都不沾。

我们来看下 RabbitMQ 是怎么扩展这部分能力的。

四、RabbitMQ 集群

既然单节点存在诸多问题,那就让多个节点构成集群。

我们可以在多个服务器上各部署一个 RabbitMQ 实例,并通过执行 RabbitMQ 提供的命令,将这些实例组成一个集群。

【图】RabbitMQ集群

RabbitMQ 支持多种集群模式。我们依次来看下。

【图】多种集群模式

普通集群模式

在普通集群模式中,每个 Broker 都是一个完整功能的 RabbitMQ 实例,都能进行读写

他们之间会互相同步 Exchange 里的元数据,但不会同步 Queue 数据。

假设 Queue1、Queue2、Queue3 分别部署在 Broker1、Broker2、Broker3中。

• 对于写操作:生产者将消息写入到 Broker1 的 Queue1 后,Queue1 里的数据并不会同步给其他 broker。但如果此时 Broker1 的 Exchange 元数据有变化,则会将元数据同步到其他两个 Broker 中。

【图】写操作

• 对于读操作:消费者想要读取 Queue1 数据时,如果访问的是 Broker1,则直接返回 Queue1 中的数据。

【图】消费消息1

但如果访问的是 Broker2,Broker2 则会根据 Exchange 里的元数据,从 Broker1 那读取数据,再返回给消费者。

【图】消费消息2

这样就可以通过增加 Broker,提升 RabbitMQ 集群整体的吞吐量,保证了扩展性。

但问题也很明显。

• 虽然支持读写 Queue 的数量是增加了,但对于单个Queue 本身的读写能力,并没有提升。

• 而且更重要的是,每个 Broker 依然有单点问题,Broker 之间并不同步 Queue 里的数据。某个 Queue 所在的 Broker 要是挂了,就没法读写这个 Queue 了。

【图】单点问题

这跟高可用毫不沾边。

有更好的方案吗?

镜像队列集群

参考下你那个,手机里有很多沸羊羊的相亲对象,没人比 ta 更懂什么是高可用。

我们可以在普通集群模式的基础上, 给 queue 在其他 broker 中加几个副本, 它们有主从关系,主 queue 负责读写数据,从 queue 负责同步复制主 queue 数据, 所以从 Queue 也叫镜像队列

一旦主 Queue 所在的 broker 挂了,从 Queue 就可以顶上成为新的主 Queue,实现高可用。这就是所谓的镜像队列集群

【图】镜像队列集群

• 对于写操作:数据写入主 Queue 后,会将 Exchange 和 Queue 数据同步给其他 Broker 上。

【图】写操作

• 对于读操作:消费者读取数据时,如果访问的是主 Queue所在的broker,则直接返回数据。

【图】消费消息1

• 否则,当前 broker 会从主 queue 所在的 broker 上读取数据,之后返回给消费者。

【图】消费消息2

但这个方案的缺点也很明显,broker 间同步的数据量会变大,集群节点越多带宽压力越大,本质上镜像队列模式是通过牺牲吞吐量换取的高可用。

反观前面的普通集群模式,虽然吞吐高但却牺牲了高可用

还是那句话,做架构做到最后,都是在做折中。又升华了。

Quorum 队列集群

看到这里不知道大家有没有发现一个问题,RabbitMQ 集群中每个节点都能知道某个 Queue 具体在哪个 Broker 上,说明 Broker 间有个机制可以互相同步元数据,但架构中却没有一个类似 kafka 的zookeeper那样的中心节点。那它是怎么在多个节点间同步数据的呢?

这是因为 RabbitMQ 基于 erlang 进行开发,这是个很特别的语言,它自带虚拟机和分布式通信框架,RabbitMQ 通过这个分布式通信框架,在 Broker 间同步元数据。

【图】基于erlang分布式通信框架同步元数据

但它有个问题,如果broker间通信断开,镜像队列可能出现多个节点都认为自己是主节点的情况,导致数据不一致,也就是所谓的脑裂问题

【图】脑裂问题

有解法吗?有!

我们可以使用更靠谱的一致性算法raft,来同步多个broker的元数据和队列数据,通过引入选举机制来解决网络分区问题,这就是所谓的 Quorum 队列集群

【图】Quorum队列集群

虽然官方推荐大家使用 Quorum 队列集群,并宣布镜像队列集群已被弃用,但目前大部分公司还是用的镜像队列集群。

嘿嘿,做架构,又不是追时髦,在成本和效率可控的情况下,人和系统,有一个能跑就行。

现在大家通了吗?

最后遗留一个问题。

想必你听说过互联网三大消息队列,kafka、rocketMQ、RabbitMQ。曾经阿里云团队对它们做过压测,同等条件下,kafka 吞吐量是每秒 17w ,rocketMQ 每秒 10w,而 RabbitMQ 则是 5w。

这就很奇怪了,RabbitMQ 虽然比 RocketMQ 功能要丰富些,但差异却并不大,为什么性能比 RocketMQ 差这么多?

如果大家感兴趣,我们有机会聊聊。

但问题又来了,我怎么才能知道大家感兴趣呢?

总结

RabbitMQ 是一个消息队列系统,它通过队列(Queue)来暂存数据,实现生产者和消费者之间的解耦,以及流量高峰时的削峰填谷。

Queue(队列)是 RabbitMQ 中的基本存储单元,用于存储消息。Exchange 是路由分发组件,用于将消息分发到一个或多个队列。

RabbitMQ 原生支持多种高级特性,如延时队列、死信队列和优先级队列。特别是优先级队列,允许根据消息的优先级进行消费,在 GPU 资源紧俏的 AI 服务场景中非常好用。

RabbitMQ 集群:为了提高性能和可用性,RabbitMQ 可以通过多节点构成集群:
• 普通集群模式:每个节点都有完整的 RabbitMQ 实例,可以实现读写分离,但单个队列的读写能力没有提升,且存在单点问题。

• 镜像队列模式:主节点将数据同步到从节点,实现高可用性,但会牺牲一定的吞吐量。

• Quorum 队列模式:通过 raft 的一致性算法来同步多个 broker 间的 queue 和元数据。

原创 靓仔白 小白debug

标签:优先级,队列,RabbitMQ,Queue,集群,图解,数据
From: https://www.cnblogs.com/o-O-oO/p/18677631

相关文章

  • Docker 安装 RabbitMQ
    目录1、下载镜像文件2、创建实例并启动创建Jenkins工作目录创建实例并启动3测试Docker集群设置集群形式1.普通模式2.镜像模式搭建镜像集群1.创建文件夹2.启动3个rabbitmq3.节点加入集群1.进入个节点完成初始化2.将节点2和3加入到集群3.访问192.168.56.131:1567......
  • RabbitMQ(三)
    RabbitMQ中的各模式及其用法工作队列模式一、生产者代码1、封装工具类2、编写代码3、发送消息效果二、消费者代码1、编写代码2、运行效果发布订阅模式一、生产者代码二、消费者代码1、消费者1号2、消费者2号三、运行效果四、小结路由模式一、生产者代码二、消费者代......
  • 深度剖析RabbitMQ:从基础组件到管理页面详解
    文章目录一、简介二、Overview2.1Overview->Totals2.2Overview->Nodesbroker的属性2.3Overview->Churnstatistics2.4Overview->Portsandcontexts2.5Overview->Exportdefinitions2.6Overview->Importdefinitions三、Connections连接的属性四、Channels通道的......
  • 探秘 RabbitMQ 管理页面:关键板块与核心功能全解析
    文章目录一、简介二、Overview2.1Overview->Totals2.2Overview->Nodes2.3Overview->Churnstatistics2.4Overview->Portsandcontexts2.5Overview->Exportdefinitions2.6Overview->Importdefinitions三、Connections四、Channels五、Exchanges六、Queues七、Ad......
  • RabbitMQ-消息消费确认
    我们一般使用的是消费者作为被动方接收RabbitMQ推送消息,另一种是消费者作为主动方可以主动拉取消息。RabbitMq服务器推送消息分为隐式(自动)确认和显示确认。1消费者拉取消息消费者作为主动方拉取消息,每次只能获取一条。using(varchannel=connection.CreateModel()){......
  • RabbitMQ-消息入队
    1分布式异步的问题对于一个业务线的处理,如果是一个完整的处理,应该是消息正常进入队列,同时消息正常被消费掉。问题来了:生产者发送消息,在传输过程中,消息丢失了,咋办?消息发到RabbitMq队列,RabbitMq宕机了,咋办?消费者在消费消息的时候,消费异常了,咋办?方案思路1、要保证消息一定能......
  • RabbitMQ-死信队列
    死信,就是无法被消费的消息,一般来说生产者将消息投递到broker或者直接到队列里了,消费者从队列取出消息进行消费。但某些时候由于特定的原因导致队列中的某些消息无法被消费,这样的消息如果没有后续的处理,就变成了死信,有死信自然就有死信队列。死信队列还是队列---只是用来接受特......
  • RabbitMQ-集群
    RabbitMQ集群----主备关系,在运行的时候,如果非主要节点宕机,程序操作不受影响;如果主节点宕机了,程序会中断操作。而Rabbitmq集群,会马上让没有宕机的节点参选,选出新的主要节点。程序重试的时候,会进入到新的节点中执行。历史消息不受影响的。基于Docker构建RabbitMQ集群1.启动......
  • RabbitMQ-优先级队列及消息配置
    优先级队列C#数据类型queue----先进先出RabbitMQ---队列-----默认也是先进先出~~RabbitMQ设置优先级----可以配置让消费顺序,不按照先进先出的默认规则;给定的优先级---最终体现在消费者;优先级越高,消费的时候,就优先消费。就在前面消费案例:设置{"vip1","hello2","wor......
  • RabbitMQ 高可用方案:原理、构建与运维全解析
    文章目录前言:1集群方案的原理2RabbitMQ高可用集群相关概念2.1设计集群的目的2.2集群配置方式2.3节点类型3集群架构3.1为什么使用集群3.2集群的特点3.3集群异常处理3.4普通集群模式3.5镜像集群模式前言:在实际生产中,RabbitMQ常以集群方案部署。因选用它......