1、RocketMQ基础概念

本文深入探讨RocketMQ源码的学习路径,从架构理解到核心组件解析,涵盖Producer、NameSrv、Broker、Consumer间的关系,及关键数据结构如BrokerAddrTable、TopicQueueTable、MessageQueue的运作机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

看RocketMQ源码看了一段时间,自己总结了下学习RocketMQ源码顺序:

1、RocketMQ架构,就是先了解下Producer、NameSrv、Broker、Consumer的简单关系。

2、RocketMQ基础概念。我最初时候是直接看源码的,没有看MQ里一些基础类的概念,也不清楚这些类,比如BrokerData、QueueData、MessageQueue、brokerAddrTable、topicQueueTable这些类的作用,所以直接看源码时很难看懂方法的作用,所以最好先把common里简单的类、数据结构了解清楚。

3、RocketMQ的nameSrv,nameSrv里面只有9个类,但写的非常简介,可以先把nameSrv搞明白。

broker集群图示如下:

上图表示一个broker集群,集群名为cluster-a,里面有两个brokerName,分别为broker-a、broker-b,broker-a又包含了一个主broker和一个从broker,其中主broker的brokerId为0,ip为10.10.10.10,从broker的brokerId为1,ip为10.10.10.11。

pay:正常情况下一台机器只有一个ip,上面只能部署一个broker实例,一主一从要用两台机器。而虚拟机有虚拟网卡,一个虚拟机上面可以部署一个broker,nameSrv可以和broker一台机器,也可以不是同一台。

broker、topic、queue关系:

  • rocketmq-common包:通用的一些类,方法,数据结构等

brokerAddrTable:HashMap<String/* brokerName */, BrokerData>;表示每个brokerName下面的一主多从的broker信息

BrokerData:里面有cluster、brokerName、brokerAddrs属性,cluster表示对应集群,brokerName表示brokerName下的一主多从broker,HashMap<Long/* brokerId */, String/* broker address */> brokerAddrs 表示哪个cluster集群下哪个brokerName下哪个brokerId对应的broker地址

topicQueueTable:HashMap<String/* topic */, List<QueueData>> topicQueueTable;表示每个topic下面的消息队列详情

QueueData:描述了会有多少消息队列MessageQueue实例。每个topic是跨多个broker的,QueueData表示一个topic在哪个broker上,有多少读、写队列,即对应的消息队列MessageQueue信息,比如topic1跨两个broker,那么queueData里面的brokerName属性这个topic在哪个broker上,readQueueNums表示这个topic在这个broker上的读队列readMessageQueue的数量,writeQueueNums为写队列writeMessageQueue的数量,perm属性表示读/写/读和写。List<QueueData>就表示一个topic在哪一个broker上面的具体信息。如下图,表示topic-A在brokerName为broker-a和broker-b上各有8个读写队列。

MessagaQueue:里面有topic、brokerName、queueId属性,表示哪个broker上的哪个topic的queueId为**的消息队列TopicRouteData:定义了topic路由的相关信息,即一个topic到哪些brokerAddr去找等等,用于网络传输。List<QueueData>表示存储在哪些broker,有多少读写/队列,List<BrokerData>表示对应的broker集合,由List<QueueData>根据RouteInfoManager#pickupTopicRouteData方法得到。HashMap<String/* brokerAddr */, List<String>/* Filter Server */>表示brokerAddr对应的filterServer地址。

TopicRouteData与属性QueueData,BrokerData关系如下图:

ConfigManager:配置管理器的父类,各种配置的管理接口,提供配置文件,加载配置,持久化配置,提供编码,解码方法。编码解码具体实现方法由实现类自己实现,比如TopicConfigManager的decode方法,先根据json串得到TopicConfigSerializeWrapper对象,如果wrapper非空,则获取topicConfigTable以及dataVersion,来更新自己的属性。

TopicConfig:定义topic的配置项,包括topicName、读对列、写队列个数,默认都是16个

dataVersion:一般用于表识数据(配置)的版本,用来辅助判断是否需要更新数据(配置)等

TopicConfigSerializeWrapper:包括topicConfigTable和dataVersion,该类继承了抽象类RemotingSerializable,封装topic配置以及版本号,用于网络传输配置以及版本。

TopicList:这个类用于将topic列表进行序列化,用于网络传输。

ClusterInfo:保存cluster信息提供给网络传输。里面有HashMap<String/* clusterName */, Set<String/* brokerName */>> clusterAddrTable,HashMap<String/* brokerName */, BrokerData> brokerAddrTable,可以查到clusterName下所有broker等。

SubscriptionData:用来形容要订阅什么样的消息数据, 并不是真正的被订阅的数据。

Message:描述最基本消息,包含消息体,topic,tag,properties,Message msg = new Message(topic, tag, data);

MessageExt:消息拓展类,继承Message,消费消息时重写consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context)方法,可以得到Message的topic、tag、body,还有MessageExt的消息存入时间StoreTimestamp、重试次数reconsumeTimes、逻辑队列长度queueOffset、物理便宜CommitLogOffset、msgId等消息信息。

MessageBatch:批量Message

  • rocketmq-broker包:接受生产者发来的消息并存储(通过调用rocketmq-store),消费者从这里取得消息。

TopicConfigManager:继承ConfigManager,用于管理Topic的配置,里面有topicConfigTable和当前配置的版本dataVersion

topicConfigTable:ConcurrentMap<String, TopicConfig> topicConfigTable,key是topicName,value是主题对应的配置

  • rocketmq-namesrv包:NameServer,类似于Zookeeper,这里保存着消息的TopicName,队列等运行时的元信息。

NamesrvStartup:NamesrvStartup 是 NameServer模块的启动入口类,启动nameSrv并注册钩子。

KVConfigManager:是namesrvController指定的kvConfig配置文件,HashMap<String/* Namespace */, HashMap<String/* Key */, String/* Value */>> configTable,可以添加、修改、查询,持久化到内存。

NamesrvConfig:NamesrvConfig是NameServer的配置类,这个类放在了common模块中,但是几乎都是被NameServer模块引用,这里就当在NameServer模块中讲。

NamesrvController:NamesrvController是NameServer服务的核心类   1、nameSrv启动 2、定时调用RouteInfoManager#scanNotActiveBroker方法,关闭2分钟没有往nameSrv发送心跳的brokerchannel连接,broker发送心跳时会更新BrokerLiveInfo的lastUpdateTimestamp值,如果这个值在当前时间的两分钟以前,说明已经2分钟没有发送心跳,关闭该brokerchannel连接。3、定时打印KVConfigManager,通过KvConfigManager.printAllPeriodically方法。

RouteInfoManager:记录路由信息。每个broker启动的时候会向namesrv注册,RouteInfoManager记录了broker注册的相关信息,Producer发送消息的时候根据topic获取路由到broker的信息, Consumer根据topic到namesrv获取topic的路由到broker的信息。RouteInfoManager使用HashMap定义了HashMap<String/* topic */, List<QueueData>> topicQueueTable,HashMap<String/* brokerName */, BrokerData> brokerAddrTable,HashMap<String/* clusterName */, Set<String/* brokerName */>> clusterAddrTable,HashMap<String/* brokerAddr */, BrokerLiveInfo> brokerLiveTable,HashMap<String/* brokerAddr */, List<String>/* Filter Server */> filterServerTable。

BrokerLiveInfo:代表一个活的broker连接,由最后更新时间,一个连接channel,数据版本和Ha地址组成,Broker定时向namesrv注册并更新BrokerLiveInfo的时间戳。

  • rocketmq-client包:提供发送、接受消息的客户端API。

TopicPublishInfo:

  • rocketmq-remoting:基于Netty4的client/server + fastjson序列化 + 自定义二进制协议

RemotingCommand:该类封装了RocketMQ的网络通信协议,服务器与客户端通过传递 RemotingCommand 对象来进行交互,包含RequestCode、CommandCustomHeader、body,以broker注册topic信息到nameSrv为例,org.apache.rocketmq.broker.out.BrokerOuterAPI#registerBroker方法,其中RequestCode可以为REGISTER_BROKER,表示注册broker信息。可以用RegisterBrokerRequestHeader实现CommandCustomHeader,RegisterBrokerRequestHeader自定义clusterName、brokerName、brokerId、brokerAddr、haServerAddr,用于指定往哪个broker上面发送,body转为json后的发送数据,比如broker注册topic到nameSrv时的RegisterBrokerBody,里面由topic的配置和filterSer。

  • rocketmq-store:消息、索引存储等

è¿éåå¾çæè¿°

ConsumeQueue中并不需要存储消息的内容,而存储的是消息在CommitLog中的offset。也就是说,ConsumeQuue其实是CommitLog的一个索引文件。ConsumeQueue是定长的结构,每1条记录固定的20个字节。很显然,Consumer消费消息的时候,要读2次:先读ConsumeQueue得到offset,再读CommitLog得到消息内容。

TransientStorePool:类名意为短暂的存储池,工作机制类似于线程池,用于池化管理多个ByteBuffer对象,进行借与还的操作。

AppendMessageStatus:写消息到commitLog时,返回的状态码,描述追加消息到日志时的状态,主要涉及消息大小与文件剩余大小的比较。

AppendMessageResult:描述写消息至commitLog时返回的结果。

PutMessageStatus:用于描述放置消息到日志时的状态。

PutMessageResult:用于描述放置消息到日志的结果。包含状态码以及追加消息的结果,前者不会为空,后者有可能为空(出现在消息预检查,还没有真正追加消息时)

FlushDiskType:SYNC_FLUSH  同步刷盘,ASYNC_FLUSH  异步刷盘

AppendMessageCallback:将消息追加到MappedFile,返回AppendMessageResult代表追加到MappedFile的结果,在MappedFile#appendMessagesInner中被调用。

ReferenceResource:MappedFile父类,作用是记录MappedFile中的引用次数,为正表示资源可用,刷盘前加一,然后将wrotePosotion的值赋给committedPosition,再减一。

SelectMappedBufferResult:提供随机读CommitLog,这个类就是描述选取MappedFile中,一部分ByteBuffer 的结果。

PutMessageLock,PutMessageSpinLock,PutMessageReentrantLock:存放消息时涉及到的锁,PutMessageSpinLock自旋锁,PutMessageReentrantLock重入锁,PutMessageSpinLock和PutMessageReentrantLock都继承PutMessageLock。

CommitLog:

MappedFile:对于 commitlog、 consumequeue、 index 三类大文件进行磁盘读写操作,均是通过 MappedFile 类来完成。

fileSize代表mappedFile文件大小,参照MessageStoreConfig.mapedFileSizeCommitLog,默认1G

fileFromOffset就是文件名称,一般为20位数字,代表这个文件开始时的offset,

wrotePosition写到的位置,当值==fileSize代表文件写满了

flushedPosition刷盘刷到的位置

committedPosition

MappedFileQueue:管理MappedFile的队列,提供了一系列根据offset或者timestamp来查找,定位,删除,清除MappedFile的逻辑,提供flushedWhere,committedWhere 标记整个队列中flush以及commit的offset。

key:用户发消息时可以指定key,多个key用逗号隔开

消息ID:消息ID在commitlog文件中并不是唯一的,消息消费重试时,发送的消息的消息ID与原先的一样。

uniqKey:消息唯一键,与消息ID不一样。

indexFile:buildIndex构建Index文件,其中将消息中的keys、uniq_keys通过putKey方法写入index文件中,keys根据空格划分为多个key。

indexService:这个类就是索引服务,提供查询key,根据key构建索引,加载IndexFile到内存,destroy过期的IndexFile等功能。

ConsumeQueue:

HAConnection:

  • rocketmq-filtersrv:消息过滤器Server,需要注意的是,要实现这种过滤,需要上传代码到MQ!
  • rocketmq-tools:命令行工具

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值