百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术教程 > 正文

深入理解MQ:RocketMQ 架构分析(rocketmq底层数据结构)

mhr18 2025-04-11 01:50 39 浏览 0 评论

1 背景

我们前面两篇对主流消息队列的基本构成和技术选型做了详细的分析。从本篇开始,我们会专注当下主流MQ之一的RocketMQ。
从他的如下的几个方面去讨论:

  • 基础能力(如 组织构成、消息发送、消息存储(持久化)、消息通信、消息消费)
  • 功能性方面(如消息堆积、消息回溯、消息追踪、消息过滤),
    高可用性方面(如 消息顺序性保障、消息幂等性保障、消息安全性保障、消息事务性保障),性能方面(如时效性,单机吞吐率)

1.1 RocketMQ是的基本组件构成

RocketMQ主要有四大核心组成部分:NameServer、Broker、Producer以及Consumer四部分。

  • NameServer:Name Server是一个几乎无状态节点,可集群部署,节点之间无任何信息同步。NameServer 是整个 RocketMQ 的 "中央大脑 " ,它是 RocketMQ 的服务注册中心,所以 RocketMQ 需要先启动 NameServer 再启动 Rocket 中的 Broker。
  • Broker: 消息服务器,作为Server提供消息核心服务, 它接收并存储Producer生产的消息,也提供消息给Consumer消费。Broker一般会分主从,Master 可读可写,Slave 只读。
  • Producer: 消息生产者,消息的发送方,负责生产消息传输给broker。RocketMQ提供了发送:同步、异步和单向(one-way)的多种模式。
  • Consumer: 消息消费者,消息的处理方,负责从broker获取消息并进行业务逻辑处理。

另外其他如 Topic、 Message,也是重要的组成部分:

  • Topic:主题,发布/订阅模式下的消息统一汇集地,不同生产者向topic发送消息,由MQ服务器分发到不同的订阅者,实现消息的广播
  • Message:消息体,根据不同通信协议定义的固定格式进行编码的数据包,来封装业务数据,实现消息的传输。

2 RocketMQ 消息架构的演进过程

2.1 简单的生产消费模式

根据我们前面所学的内容,消息队列很重要的一个工作就是对生产和消费者进行解耦的过程。有人负责生产,有人负责消费,两者没有直接交互,交给中介者去处理。

比如说系统A会交给系统B去处理一些事情,但是A不想直接跟B有关联,避免耦合太强,就可以通过在A,B中间加入消息队列,A将要任务的事情交给消息队列 ,B订阅消息队列来执行任务。

这种典型的模式是由两个线程和一个队列构成:

  • 生产者线程:生产任务,并把任务推送到队列里。
  • 消费者线程:从队列里面获取任务,并进行任务处理操作,这就是消费的过程。

    目前这种还只是初级版本的 生产-消费者模式,构成了基本的消息队列 。另外为了消息队列的可用性,我们一般会把消费者,队列,生产者放到不同的服务机上,变成分布式消息队列,这样哪怕消费者所在的主机挂了,依旧不影响消息生产。

2.2 Topic模式对消息进行归类

主题(Topic)可以看做消息的归类,我们将消息进行类型划分,相同类型的消息称为一个 Topic。比如我们在淘宝或京东上购买商品的的过程,就可能产生:购物车消息、交易消息、物流消息等,1条消息必然归属于1个 Topic 。

1个 Topic可以有0 ~ n 个生产者向其发送消息;也可以被 0~n 个消费者订阅和处理,于是就又出现了生产者组和消费者组,如下图:

2.3 Broker 集群模式

随着生产者和消费者的不断扩大,原本单一的Broker数据处理的能力始终是有限的(无论是被写入、存储或者被消费),所以这个时候就需要对Broker进行scale out,来分担单机的压力。我们称之为 Broker 集群模式。在 微服务系列、MySQL系列、Redis系列 中,我们已经了解过很多Cluster模式的案例。


这边需要注意,每个Broker 可以包含1个 Broker Master 和 至少 1个Broker Slave ,所以它是主从结构,通过 Data Sync、Async 来进行数据同步。Producer 只能将消息发送到 Broker Master,但是 Consumer 同时和Broker Master和 Broker Slave 建立长连接,既可以从 Master 订阅消息,也可以从 Slave 订阅消息。

Broker Master:可以用于消息生产,也可以用于消息消费,并将消息数据 Sync / Async 到Slave。

Broker Slave:只能用于消息消费。

2.4 使用 NameServer 来进行路由管理

我们既然使用了Broker Cluster模式,那么就会有多个Broker实例。这时候就有新的问题了,producer生产的消息需要发送到哪个Broker中,comsumer又要去哪个Broker里面去取数据,都需要梳理清楚,不然就很混乱。RocketMQ摒弃了业界常用的zookeeper作为注册中心(比如Kafka),而是使用自研的 NameServer 来管理 具有映射关系的路由信息。由它来告诉producer,某个 Topic 的消息可以发给哪些队列,同时告诉consumer可以从哪些队列里面获取你需要的消息。NameServer 也可以有很多个,组成 NameServer 集群。

总的来说,NameServer是一个功能完整的命名服务组件,提供轻量级的服务发现及完整路由信息记录能力,主要包含两个功能:

  • Broker 管理,接收来自 Broker 集群的注册请求,提供心跳机制,检测 Broker 是否存活。
  • 路由管理,每个 NameServer 持有全部有关 Broker 集群和客户端请求队列的路由信息。

详细运行流程可以参考如下:


上述的流程图比较清晰的描述如下运转流程:

  • NameServer 优先启动。NameServer 是整个 RocketMQ 的“中央大脑” ,作为 RocketMQ 的服务注册中心,所以 RocketMQ 需要先启动 NameServer 再启动 Rocket 中的 Broker。
  • Broker 启动后,与 NameServer 保持长连接,每 30s 发送一次发送心跳包,来确保Broker是否存活。并将 Broker 信息 ( IP+、端口等信息)以及Broker中存储的Topic信息上报。注册成功后,NameServer 集群中就有 Topic 跟 Broker 的映射关系。
  • NameServer 如果检测到Broker 宕机(因为使用心跳机制, 如果检测超120s(两分钟)无响应),则从路由注册表中将其移除。
  • 生产者在发送某个主题的消息之前先从 NamerServer 获取 Broker 服务器地址列表(Broker可能是Cluster模式),然后根据负载均衡算法从列表中选择1台Broker ,建立连接通道,进行消息发送。
  • 消费者在订阅某个topic的消息之前从 NamerServer 获取 Broker 服务器地址列表(Broker可能是Cluster模式),包括关联的全部Topic队列信息。进而获取当前订阅 Topic 存在哪些 Broker 上,然后直接跟 Broker 建立连接通道,开始消费数据。
  • 生产者和消费者默认每30s 从 NamerServer 获取 Broker 服务器地址列表,以及关联的所有Topic队列信息,更新到Client本地。

3 总结

Topic 主要是为了将消息进行归类,同一个业务中消息繁复,我们将消息按照特性进行划分,相同类型的消息称为一个 Topic。

当业务不断膨胀的时候,需要对Broker进行集群化,每个Broker实例包含1个 Broker Master 和 至少 1个Broker Slave ,通过 Data Sync、Async 来进行数据同步,这样达到生产和消费分离。

使用 NameServer 来进行 Broker 注册和管理,接收来自 Broker 集群的注册请求,提供心跳机制,检测 Broker 是否存活。

NameServer 也用来进行路由管理,来保证 producer生产的消息需要发送到哪个Broker中,comsumer又要去哪个Broker里面去取数据。


为帮助开发者们提升面试技能、有机会入职BATJ等大厂公司,特别制作了这个专辑——这一次整体放出。

大致内容包括了: Java 集合、JVM、多线程、并发编程、设计模式、Spring全家桶、Java、MyBatis、ZooKeeper、Dubbo、Elasticsearch、Memcached、MongoDB、Redis、MySQL、RabbitMQ、Kafka、Linux、Netty、Tomcat等大厂面试题等、等技术栈!

欢迎大家关注公众号【Java烂猪皮】,回复【666】,获取以上最新Java后端架构VIP学习资料以及视频学习教程,然后一起学习,一文在手,面试我有。

每一个专栏都是大家非常关心,和非常有价值的话题,如果我的文章对你有所帮助,还请帮忙点赞、好评、转发一下,你的支持会激励我输出更高质量的文章,非常感谢!

相关推荐

Redis合集-使用benchmark性能测试

采用开源Redis的redis-benchmark工具进行压测,它是Redis官方的性能测试工具,可以有效地测试Redis服务的性能。本次测试使用Redis官方最新的代码进行编译,详情请参见Redis...

Java简历总被已读不回?面试挂到怀疑人生?这几点你可能真没做好

最近看了几十份简历,发现大部分人不是技术差,而是不会“卖自己”——一、简历死穴:你写的不是经验,是岗位说明书!反面教材:ד使用SpringBoot开发项目”ד负责用户模块功能实现”救命写法:...

redission YYDS(redission官网)

每天分享一个架构知识Redission是一个基于Redis的分布式Java锁框架,它提供了各种锁实现,包括可重入锁、公平锁、读写锁等。使用Redission可以方便地实现分布式锁。red...

从数据库行锁到分布式事务:电商库存防超卖的九重劫难与破局之道

2023年6月18日我们维护的电商平台在零点刚过3秒就遭遇了严重事故。监控大屏显示某爆款手机SKU_IPHONE13_PRO_MAX在库存仅剩500台时,订单系统却产生了1200笔有效订单。事故复盘发...

SpringBoot系列——实战11:接口幂等性的形而上思...

欢迎关注、点赞、收藏。幂等性不仅是一种技术需求,更是数字文明对确定性追求的体现。在充满不确定性的网络世界中,它为我们建立起可依赖的存在秩序,这或许正是技术哲学最深刻的价值所在。幂等性的本质困境在支付系...

如何优化系统架构设计缓解流量压力提升并发性能?Java实战分享

如何优化系统架构设计缓解流量压力提升并发性能?Java实战分享在高流量场景下。首先,我需要回忆一下常见的优化策略,比如负载均衡、缓存、数据库优化、微服务拆分这些。不过,可能还需要考虑用户的具体情况,比...

Java面试题: 项目开发中的有哪些成长?该如何回答

在Java面试中,当被问到“项目中的成长点”时,面试官不仅想了解你的技术能力,更希望看到你的问题解决能力、学习迭代意识以及对项目的深度思考。以下是回答的策略和示例,帮助你清晰、有说服力地展示成长点:一...

互联网大厂后端必看!Spring Boot 如何实现高并发抢券逻辑?

你有没有遇到过这样的情况?在电商大促时,系统上线了抢券活动,结果活动刚一开始,服务器就不堪重负,出现超卖、系统崩溃等问题。又或者用户疯狂点击抢券按钮,最后却被告知无券可抢,体验极差。作为互联网大厂的后...

每日一题 |10W QPS高并发限流方案设计(含真实代码)

面试场景还原面试官:“如果系统要承载10WQPS的高并发流量,你会如何设计限流方案?”你:“(稳住,我要从限流算法到分布式架构全盘分析)…”一、为什么需要限流?核心矛盾:系统资源(CPU/内存/数据...

Java面试题:服务雪崩如何解决?90%人栽了

服务雪崩是指微服务架构中,由于某个服务出现故障,导致故障在服务之间不断传递和扩散,最终造成整个系统崩溃的现象。以下是一些解决服务雪崩问题的常见方法:限流限制请求速率:通过限流算法(如令牌桶算法、漏桶算...

面试题官:高并发经验有吗,并发量多少,如何回复?

一、有实际高并发经验(建议结构)直接量化"在XX项目中,系统日活用户约XX万,核心接口峰值QPS达到XX,TPS处理能力为XX/秒。通过压力测试验证过XX并发线程下的稳定性。"技术方案...

瞬时流量高并发“保命指南”:这样做系统稳如泰山,老板跪求加薪

“系统崩了,用户骂了,年终奖飞了!”——这是多少程序员在瞬时大流量下的真实噩梦?双11秒杀、春运抢票、直播带货……每秒百万请求的冲击,你的代码扛得住吗?2025年了,为什么你的系统一遇高并发就“躺平”...

其实很多Java工程师不是能力不够,是没找到展示自己的正确姿势。

其实很多Java工程师不是能力不够,是没找到展示自己的正确姿势。比如上周有个小伙伴找我,五年经验但简历全是'参与系统设计''优化接口性能'这种空话。我就问他:你做的秒杀...

PHP技能评测(php等级考试)

公司出了一些自我评测的PHP题目,现将题目和答案记录于此,以方便记忆。1.魔术函数有哪些,分别在什么时候调用?__construct(),类的构造函数__destruct(),类的析构函数__cal...

你的简历在HR眼里是青铜还是王者?

你的简历在HR眼里是青铜还是王者?兄弟,简历投了100份没反应?面试总在第三轮被刷?别急着怀疑人生,你可能只是踩了这些"隐形求职雷"。帮3630+程序员改简历+面试指导和处理空窗期时间...

取消回复欢迎 发表评论: