1.RocketMQ主要解决项目中什么问题?
- 流量削峰
内容不同来源的信息加入队列,同步系统进行消费,对内容进行处理; 支付场景:上有不同业务线订单收集到队列中,然后对订单进行处理;
- 异步解耦
将支付单加入延迟队列进行查询
- 数据归集
发送支付成功订单到对账系统; 数据清洗-增量数据同步:使用cacel监听binlog 然后将增量数据同步到新系统
- 压力测试
2.RocketMQ常用的协议有哪些?
- RocketMQ的协议基于TCP协议,客户端与服务端之间建立TCP链接连进行数据传输
- 扩展:一共有哪些协议?
- TCP:用于可靠的传输数据,他是互联网协议的套件(TCP/IP)中的一部分, 优点: 可靠行(确认机制,流量控制和拥塞控制等多种技术) 有序性,双全工通信(充许通信双方同时传输),链接管理(建立和拆除比较简单), 错误检查进行重试;
- UDP:是一种无链接的传输协议,不提供数据的可靠性,但是可以实现数据的快速传输; 传输时候不需要建立链接可以实现多对多的通信;使用场景:视频会议/在线游戏
- HTTP:是一种应用层协议,用于客户端和服务端之间传输超文本数据,如网页,文件,图片, 优点:简单易用,支持多种数据类型,应用广泛;缺点:比较慢,不适合大文件传输;
- FTP:是一种文件传输协议,支持批量文件传世和文件夹操作,优点:支持文件的上传和下载 传输速度比较快,缺点:需要建立链接,安全性比较差;
- SMTP:是一种电子邮件传输协议,用于邮件服务器之间的传输,优点:简单易用,支持多种格式, 缺点:不支持附件的传输;安全性比较低;
3.项目中使用的RocketMQ版本是哪个?
- 4.8.0
4.RocketMQ 整体架构?
- NameServer
管理Broker:NameServer 是一个无状态节点,可集群部署,节点之间无任何信息同步。
- Broker
暂存和传输消息。如:邮局 Broker 部署相对复杂,Broker 分为 Master 和 Slave,一个 Master 可以对应多个 Slave,但是一个 Slave 只能对应一个 Master,Master 与 Slave 的对应关系通过指定相同的 BrokerName,不同的 BrokerId 来定义,BrokerId 为 0 表示为 Master ,非 0 表示 Slave 。Master 也可以部署多个。 每个 Broker 与 NameServer 集群中的所有节点建立长连接,定时注册 Topic 信息到所有 NameServer。 注意:当前 RocketMQ 版本在部署架构上支持一 Master 多 Slave,但只有 BrokerId = 1 的从服务器才会参与消息的读负载。
- Producer
消息发送者。如:发信者 Producer 完全无状态,可集群部署 Producer 与 NameServer 集群中的其中一个节点(随机选择)建立长连接,定期从 NameServer 获取 Topic 路由信息,并向提供 Topic 服务的 Master 建立长连接,且定时向 Master 发送心跳。
- Consumer
消息接收者。如:收信者 Consumer 与 NameServer 集群中的其中一个节点(随机选择)建立长连接,定期从 NameServer 获取 Topic 路由信息,并向提供 Topic 服务的 Master、Slave 建立长连接,且定时向 Master、Slave 发送心跳。 Consumer 既可以从 Master 订阅消息,也可以从 Slave 订阅消息,消费者在向 Master 拉取消息时,Master 服务器会根据拉取偏移量与最大偏移量的距离(判断是否读老消息,产生读I/O),以及从服务器是否可读等因素建议下一次是从 Master 还是 Slave 拉取。
5.RocketMQ工作流程?
1.启动 NameServer,NameServer 启动后监听端口,等待 Broker、Producer、Consumer 连上来,相当于一个路由控制中心。
2.Broker 启动,跟所有的 NameServer 保持长连接,定时发送心跳包。心跳包中包含当前 Broker 信息(IP+端口等)以及存储所有Topic信息。注册成功后,NameServer 集群中就有 Topic 跟 Broke r的映射关系。
3.收发消息前,先创建 Topic,创建 Topic 时需要指定该 Topic 要存储在哪些 Broker 上,也可以在发送消息时自动创建 Topic。
4.Producer 发送消息,启动时先跟 NameServer 集群中的其中一台建立长连接,并从 NameServer 中获取当前发送的 Topic 存在哪些 Broker 上,轮询从队列列表中选择一个队列,然后与队列所在的 Broker 建立长连接从而向 Broker 发消息。
5.Consumer 跟 Producer 类似,跟其中一台 NameServer 建立长连接,获取当前订阅 Topic 存在哪些 Broker 上,然后直接跟 Broker 建立连接通道,开始消费消息。
6.RocketMQ的queue与consmuer的构成关系?
- 创建topic的两种方式:
提前创建:提前创建分为:集群模式下创建(在每个Broker创建相同的queue 默认情况下是4个) 和 broker下创建(可以规定每一个queue的数量)
- queue与consmuer的关系:
一个consmuer可以消费多个queue,但是一个queue只能对一个消费;
7.RocketMQ集群的搭建方式?
-
单Master模式
这种方式风险较大,一日 Broker 重启或者宕机时,会导致整个服务不可用。不建议线上环境使用,可以用干本地测试。
-
多Master模式
一个集群无 Slave,全是 Master,例如2个 Master 或者3个 Master,这种模式的优缺点如下:
优点:
配置简单,单个 Master 宕机或重启维护对应用无影响,在磁盘配置为 RAID10时,即使机器宕机不可恢复情况下,由于 RAID10磁盘非常可靠,消息也不会丢(异步刷盘丢失少量消息,同步刷盘一条不丢),性能最高。
缺点:
单台机器宕机期间,这台机器上未被消费的消息在机器恢复之前不可订阅,消息实时性会受到影响。
-
多Master多Slave模式(异步)
每个 Master 配置一个 Slave,有多对 Master-Slave,HA采用异步复制方式,主备有短暂消息延迟(毫秒级),
优点:
即使磁盘损坏,消息丢失的非常少,目消息实时性不会受影响,同时 Master 宕机后,消费者仍然可以从 Slave 消费,而目此过程对应用透明,不需要人工干预,性能同多 Master 模式几乎一样。
缺点:
Master 宕机,磁盘损坏情况下会丢失少量消息。
-
多Master多Slave模式(同步)
每个 Master 配置一个 Slave,有多对Master-Slave,HA 采用同步双写方式,即只有主备都写成功,才向应用返回成功,这种模式的优缺点如下:
优点:
数据与服务都无单点故障,Master 宕机情况下,消息无延迟,服务可用性与数据可 用性都非常高
缺点:
性能比异步复制模式略低(大约低10%左右),发送单个消息的RT会略高,且目前版 本在主节点宕机后,备机不能自动切换为主机。
8.RocketMQ中的刷盘和复制策略?
- 同步刷盘:同步到磁盘后返回ACK
- 异步刷盘:写入缓存后返回ACK
- 同步复制:同步到slave后返回ACK(salve不能自动切换为主)
- 异步复制:写入缓存返回ACK
9.生产者发送消息的过程?选择Queue的策略? 重试机制?
-
生产者发送消息过程:
- Product发送消息之前,会向NameServer发出获取Topic的路由信息的请求
- NameServer返回Topic的 路由表 和 Broker列表
- Product根据代码中指定的Queu选择策略,从Queue中列表中选出一个队列,用于后续存储消息
- Product对消息做一些统一的处理,比如:消息本身超过4M,则会进行压缩
- Product向选择出的Queue所在的Broker发出RPC的请求,将消息发送到选择出的Queue
-
生产者发送时选择Queue的策略,对于无序消息,其Queue的选择算法,也称之为消息投递算法,常见有两种:
- 轮询算法:默认选择算法,该算法保证了每个Queue可以均匀的获取到消息;该算法存在问题,由于某些原因没在某些broker上的Queue可能投递延迟,从而导致product缓存队列中出现较大消息积压,影响投递性能;
- 最小投递延迟算法 :该算法会统计每次消息投递的延迟时间,然后根据统计结果将消息投递到时间延迟最小的Queue中,如果延迟相同,则采用轮询算法投递,该算法可以有效的提升消息的投递性能;RT代表延迟时间;缺点:会造成Queue分配消息不均匀,消费者集群会导致某个压力过大;
-
生产者重试机制:
-
生产者在发送消息的时候,若采用同步和异步发送,是会有重试机制的,但是单向发送是不会重试,2次重试;只有普通消息有重试机制
-
同步发送失败策略
- 默认两次,第二次发送不会选择上一次的queue中;所以顺序消息没有重试机制
- 重试次数达到两次后,没有成功会抛出异常;当然生产者出现RemitingException MQClientException和MQBrokerException,product会自动重试投递消息;
- 选择其他broker
- broker全挂会导致消息丢失
-
异步发送失败策略
- 不会选择其他的broker进行再次投递,仅仅在一个broker上重试
- 会导致消息丢失
-
消息刷盘失败策略
- 消息刷盘时slave不可用,默认不会将消息尝试发送到其他broker中,不过对于重要的消息可以设置成重试机制
-
10.RocketMQ消息消费的方式有那些,各有什么优缺点?
- broker获取维度分为两种:
- pull模式:消费者主动拉取消息 优点:不浪费系统资源,不用建立长链接;缺点:消费和自己主动掌握拉取时间,消息的实时性较差;
- push:发布订阅broker主动推送,Consumer向关联的Queue注册了监听器 优点:消息的实时性很好,但是需要建立长链接,浪费系统资源;
- 消费组的维度分为两种:
- 集群消费:每个消费者按照queueu的分配策略进行分配拉取那个Queue,或者broker进行推送;
- 广播模式:广播需要broker把消息发送到每个消费的参与者,拉取方式的集群模式不能保证每个consumer消费的进度是一定的;
- 注意:
- 广播模式消息进度保存:消费进度保存在consumer端,因为广播模式下consumer group中每个consumer都会消费所有的消息,但他们的消费进度是不同,所以consumer各自保存各自的消费进度。
- 集群模式消息进度保存:消费进度是保存在broker中,consumer group中的所有consumer共同消费同一个topic中消息,同一个消息只会被消费一次,消费进度会参与到消费的负载均衡中,固消费进度是需要共享的。
11.broker中消息写入的流程?
- Broker根据queueId,获取到该消息对应索引条目要在consumequeue目录中的写入偏移量,即QueueOffset
- 将queueId,queueOffset等数据,与消息一起分装为消息单元
- 将消息单元写入commitlog
- 同时形成消息索引条目
- 将消息索引条目发送到相应的consumequeue
12.broker中消息消费的流程?
- consumer获取到其要消费消息所在的queue的消费偏移量offset(消费进度),计算出其要消费消息的offset
- 注释:消费offset即消费的进度,consumer对某个Queue的消费offset,即消费到了该queue的第几条消息;消息offset就是消费offset + 1
- consumer向broker发送拉取请求,其中会包含要拉取消息的queue,消息offset及消息tag
- broker 计算在该consumequeue中的queueOffset
- 从该queueOffset出开始向后查找第一个指定tag的索引目录
- 解析该索引条目的前8个字节,即可定位到该消息在commitlog和commitlog offset
- 从对应的commitlog offset中读取消息单元,并发送给consumer
13.什么是Rebalance机制?过程?会影响什么?
- 概念:集群模式,再均衡再次分配,一个topic中在新增consumer时要进行再分配的过程;
- 限制:集群模式,consumer的数量小于或等于消费的queue数量;
- 危害:
- 消费暂停:在一个consumer-A正在消费一个topic下queue时,增加一个consumer-B时,consumer-A会停止消费,需要重新分配consumer和queue之间的关系,分配完成后才会再次消费;
- 消费重复:增加消费者时,无论是新的消费者还是之前的消费者都必须按照之前的queue的offset进行消费,但是在offset保存时是采用异步提交方式,这样会导致时间差的问题,也就是原有消费者产生的offset还没有在broker中进行提交,新的消费者就开始消费了;同步提交没有这种影响,同步提交是返回ACK,消费者才会进行下一次消费;
- 消费突刺:由于发生了Rebalance时,可能会影响大量消息堆积,在开始消费时有大量数据会进行消费;
14.RocketMQ在分配Queue选择consumer时候,是什么策略??
必须遵循最少一次原则;
- 平均分配策略:一个topic中创建了10(0~9)个queue,有4(a,b,c,d)个消费者消费;策略:a -0,1,2 / b-3,4,5 /c-6,7 /d-8,9,规则:先计算好每个comsumer分配几个,然后再分配
- 环形平均策略:规则 不需要先计算consumer分配几个 直接按照环形分配就可以;
- 一致hash算法策略:ConsumerId设置在hash环上 queue进行计算后放置在环的空间
- 同机房策略:broker分配在不同城市,比如杭州机房 北京机房,consumer根据不同地区进行消费;
优缺点总结;
- 平均分配算法和环形平均算法,效率比较高,一致hash比较复杂所以效率比较低;
- 在发生Rebalanec时,一致hash要比平均算法占优势,解决的问题是在缩容和扩容是不会Rebalance太多;
15.消息什么时候会被重复消费?怎么保证消息不会重复被消费?怎么实现?
- 消息什么时候会被重复消费
- product发送消息重复:当product进行消费发送时,当发送到broker后进行了持久化,出现了网络问题,此时product不会接收到发送成功的响应,如果业务中的product会进行重试,再次发送会导致重复发送,当然这个时候messageID和msg与之前的是一致的;
- consumer消费消息重复:当consumer消费完成后,向broker发送offset的提交,此时网络异常,为了保证至少一次的原则,broker会再次尝试投递之前已被处理的消息,和之前的消息内容 msgID是一致的;
- Rebalance时消息重复:在consumer进行异步提交时,扩容或缩容consumer/queue时会导致Rebalance,同时在异步提交时会产生消费的重复;
- 怎么保证消息不会重复被消费
- 幂等令牌:订单id/key/msgId;
- 唯一性处理:业务处理跟踪状态,在修改前校验数据是否被修改;
- 怎么实现
- 首先通过缓存redis去重
- 再通过唯一性去重,唯一性去重是指:查询数据库中是否存在幂等令牌,第二部去重是为了防止redis中的数据过期;
- 在同一个事物中做三件事:唯一性处理后,幂等令牌写入缓存,并将幂等令牌作为唯一键写入DB,加入缓存是为了防止缓存穿透;
- 不建议使用MSgID作为幂等令牌,可以使用业务唯一的key或业务单号,因为msgID可能会重复;
16.消息堆积及消费的延迟的概念?产生的原因?如何避免?
- 概念
- 消息处理中,如果consumer消费速度跟不上product的生产速度,会造成堆积消息,发生了消息堆积会造成消费延迟;
- 业务系统上下游的能力不匹配造成持续堆积,且无法自动恢复
- 业务系统对消息的消费实时性较高,即使是短暂的堆积造成的消费延迟也无法接受
- 产生的原因
- 消息堆积及消费的延迟主要关注,消费耗时和消费并发度,消费的耗时要高于消费并发度,先降低代码层面的逻辑耗时,然后再考虑消费的并发度;
- 消费耗时
代码逻辑中耗时的类型有两种 cpu内部计算代码:只要代码中没有复杂的循环和递归,一般就不用考虑 外部I/O操作型代码 如下: 读写外部数据库; 读写外部缓存redis; 下游系统调用 如Rpc调用 http接口,导致耗时的原因一般是服务异常 和 DBMS的容量限制,服务异常:用户量评估失误,代码错误,网络带宽太小等;
- 消费的并发度
一般情况下,消费并发度是consumer所用的线程数 和 多少个consumer来决定 消费并发度=单节点线程数节点数 对于普通消息和延迟消息并发度是单节点线程数节点数,而顺序消息 消息并发度=Queue分区数 全局顺序消息:只有一个queue,只有一个consmuer进行消费; 分区顺序消息:多个queue,消费者的数量=queue分区的数量;保证每个consumer消费对应的queue是有顺序的;消费并发度=queue的分区数量;
- 如何避免
梳理消费耗时和消费并发度 梳理消费的耗时:通过压测来确认消息的耗时,梳理包含以下几步: 消费逻辑的计算复杂度是否过高,代码是否有循环和递归 消费逻辑中的I/O操作是否必要的,能否用缓存替代 消费逻辑中的复杂耗时是否可以通过异步处理,如果可以是否可保证逻辑 梳理消费并发度,梳理包含以下几步: 逐步调大单个Consumer节点的线程数,并观测节点的系统指标,得到单个节点最后的消费线程数和消息吞吐量 根据上游的流量峰值计算出需要设置几个Consumer节点进行消费
17.如何保证消息不丢失?
-
可以从以下三个方面考虑消息不丢失,但是要根据业务场景进行选用,因为保证数据不丢失,同时也会降低性能,需要权衡;
-
Producer 发送消息
- 同步发送,同步返回ACK,异常情况有四种:根据返回的状态码,可以做消息重试,这里设置的重试次数是 3。
消息重试时,消费端一定要做好幂等处理。
- SEND_OK:消息发送成功。需要注意的是,消息发送到 broker 后,还有两个操作:消息刷盘和消息同步到 slave 节点,默认这两个操作都是异步的,只有把这两个操作都改为同步,SEND_OK 这个状态才能真正表示发送成功。
- FLUSH_DISK_TIMEOUT:消息发送成功但是消息刷盘超时。
- FLUSH_SLAVE_TIMEOUT:消息发送成功但是消息同步到 slave 节点时超时。
- SLAVE_NOT_AVAILABLE:消息发送成功但是 broker 的 slave 节点不可用。
- 异步发送:异步发送,可以重写回调函数,回调函数捕获到 Exception 时表示发送失败,这时可以进行重试,这里设置的重试次数是 3。
- 同步发送,同步返回ACK,异常情况有四种:根据返回的状态码,可以做消息重试,这里设置的重试次数是 3。
消息重试时,消费端一定要做好幂等处理。
-
Broker 保存消息
- 主要考虑刷盘和复制策略
- 异步刷盘:默认。消息写入 CommitLog 时,并不会直接写入磁盘,而是先写入 PageCache 缓存后返回成功,然后用后台线程异步把消息刷入磁盘。异步刷盘提高了消息吞吐量,但是可能会有消息丢失的情况,比如断点导致机器停机,PageCache 中没来得及刷盘的消息就会丢失。
- 同步刷盘:消息写入内存后,立刻请求刷盘线程进行刷盘,如果消息未在约定的时间内(默认 5 s)刷盘成功,就返回 FLUSH_DISK_TIMEOUT,Producer 收到这个响应后,可以进行重试。同步刷盘策略保证了消息的可靠性,同时降低了吞吐量,增加了延迟。要开启同步刷盘,需要增加下面配置: flushDiskType=SYNC_FLUSH 3.异步复制:默认是异步的,即 master 收到消息后,不等 slave 节点复制消息就直接给 Producer 返回成功。 这样会有一个问题,如果 slave 节点还没有完成消息复制,这时 master 宕机了,进行主备切换后就会有消息丢失。为了避免这个问题,可以采用 slave 节点同步复制消息,即等 slave 节点复制消息成功后再给 Producer 返回发送成功。只需要增加下面的配置: brokerRole=SYNC_MASTER 4.同步复制:slave 初始化后,跟 master 建立连接并向 master 发送自己的 offset; master 收到 slave 发送的 offset 后,将 offset 后面的消息批量发送给 slave; slave 把收到的消息写入 commitLog 文件,并给 master 发送新的 offset; master 收到新的 offset 后,如果 offset >= producer 发送消息后的 offset,给 Producer 返回 SEND_OK。
- 主要考虑刷盘和复制策略
-
Consumer 消费消息
- 需要采用消息确认机制:如果 Consumer 消费成功,返回 CONSUME_SUCCESS,提交 offset 并从 Broker 拉取下一批消息
- Consumer 消费失败,这里有 3 种情况:
- 返回 RECONSUME_LATER
- 返回 null
- 抛出异常 Broker 收到这个响应后,会把这条消息放入重试队列,重新发送给 Consumer。
注意:
Broker 默认最多重试 16 次,如果重试 16 次都失败,就把这条消息放入死信队列,Consumer 可以订阅死信队列进行消费。 重试只有在集群模式(MessageModel.CLUSTERING)下生效,在广播模式(MessageModel.BROADCASTING)下是不生效的。 Consumer 端一定要做好幂等处理。 其实重试 3 次都失败就可以说明代码有问题,这时 Consumer 可以把消息存入本地,给 Broker 返回CONSUME_SUCCESS 来结束重试
18.被消费过的消息会马上被处理掉吗?RocketMQ如何清理消息?
- 消息被消费后不会立即清理,因为这样会影响效率;
- 消息的清理是是以commitlog文件来清理的,每个文件存储大量的消息单元,如果按照消息单元处理,会很影响效率;
- commitlog文件存在一个“过期时间”,默认是72小时;
- 有以下几种情况,无论消息是否被消费过够会进行清理
- 文件过期,超过默认的72小时,且达到了清理时间,默认是凌晨4点后,会自动清除;
- 文件过期,磁盘占有率达到了默认的75%后,无论是否达到清除时间点都会自动清理过期文件;
- 无论文件是否过期,磁盘占有率超过了85%,从最老文件开始清理;
- 无论文件是否过期,磁盘占有率超过了95%后,broker拒绝消息的写入;
- 对于commitlog文件默认是1个G,在删除过程中,很浪费系统性能,使RocketMq的性能极聚下降;所以在凌晨4点
- 官方建议RocketMQ服务的liunx文件系统采用ext4,因为对于文件操作ext4要比ext3好些;
19.消息发送有哪几种方式,消息有几种类型?分别是怎么实现的?
-
发送方式:
- 单向发送:直接发送不会返回ACk
- 异步发送:发送后异步返回ACk
- 同步发送:发送后同步返回ACK
-
消息类型:
-
事物消息
半事务消息机制 步骤:
-
顺序消息
全局顺序消息:一个queue 一个consumer 生产者没有重试机制(需要自己写重试逻辑) 消费者消费失败会阻塞
分区顺序消息:在produc中定义消息队列选择器,实现定义好的接口MessageQueueSelector,一般是指定格唯一的key,然后和queue的数量取模;Consumer对获取的key进行判断,如果是当前consumer需要消费的,就直接消费,否则直接跳过;这样会导致消息不能被处理就扔回queue中,其他consuumer group的consumer会继续消费;
-
延时队列消息
- 延迟18个级别:LmessageDelayLevel=1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h*
- 实现步骤 a.多少啊
- 定时消息(略)
- 批量消息(略)
- 消息回溯(略)
-
20.什么是重试队列,死信队列,消费失败返回几种方式?
- 重试队列:
- 当rocketmq对消息的消费出现异常时候,会将发生异常消息的offset提交到broker中的重试队列, 系统在发生消息消费异常时会为当前topic@group创建一个重试队列,该队列以%RETRY%开始,到达重试时间的时候重新消费;
- Broker对重试的处理是通过延迟消息实现的,先将消息保存到SCHEDULE_TOPIC_XXX延迟队列中,延迟时间到后, 会将消息投递到“%RETRY%@ConsumerGroup@ConsumerGroup”重试队列中
- 如果默认16次后仍然失败,会把消息放入死信队列;
- 死信队列
- 死信队列中消息不会再次被消费
- 死信队列中的消息保存72小时
- 死信队列是一个特殊的TOPIC,名字为%DLQ@ConsumerGroup@ConsumerGroup%
- 消费失败返回几种方式
- return ConsumeConcurrentlyStatus.RECONSUME_LATEB
- return null
- throw new RuntimeException();
- 注意
- 顺序消息的重试:不断的重试,只到成功,会导致其他后续消息被阻塞;保证应用及时监控做处理,避免永远性阻塞;默认是1000ms重试一次
- 对于无序的消息,通过返回给broker相应的状态,会达到重试的机制,但是实在集群消费模式下才会生效; 对于无序消息,广播模式不提供重试机制;
21.横向对比目前的MQ中间件,都有那些优点和缺点?
22.RocketMQ消息存储store目录下都有哪些文件夹?各是什么作用?
- *commitLog文件
- 所有消息存放在commitlog中,一个broker中仅仅包含一个conmitfile文件,一个commitfile文件中有多个mappedfile文件, 文件大小是1G,文件名有20位十进制数据构成,表示当前文件的第一条消息的起始位偏移量。,无论broker下面有多少个topic, 消息都会被顺序写入,并没有按照topic分类写入,所以访问效率很高;
- mappedFile文件内容由一个个消息单元构成,每个消息单元中包含消息总长度,消息的物理位置,消息体内容,消息体长度,消息主题,主题长度,消息生产者,消息发送时间戳,消息所在队列的ID, 消息在queue中存储的偏移量queueoffset等近20余项消息相关属性。
- *consumerqueue文件
- 是commitlog文件的索引
- 每个topic在consumerqueue文件中都会创建一个目录,文件名称就是topic的名称,在topic里每一个queue会创建一个文件,文件名称是queueId
- 在文件中会存着消息在commitlog文件映射的偏移量commitOffset,消息长度MsgLen,消息tag的hashcode值,所以每个文件固定是30*20byte
- abort
- 该文件在borker启动后会自动创建,正常关闭broker,该文件会自动消失,若在没有启动broker的情况下,发现这个文件是存在的,说明broker是非正常关闭的
- config
- 存放着broker运行期间的一些配置数据;
- index
- 如果在发送消息的时候有key值存在,Broker就会放入这个文件,提供以key的方式去查询,在生产者(key由消费者业务指定)消息发送到broker时候写入;
- checkpoint
- 其中存储的commitlog,consumequeue,inex文件最后的刷盘的时间戳;
- lock
- 运行期间使用到的全局资源锁 目录与文件 消息单元
23.RocketMQ的核心源码可以简单说下吗?