RocketMQ源码学习 (九) Broker 服务端“拉消息”请求处理逻辑

1 DefaultMessageStore类

在上一篇文章中讲到PullMessageProcessor处理器在拉取消息的时候调用了defaultMessageStore.getMessage方法,本篇内容主要探究该方法的的DefaultMessageStore类和其主要方法
在这里插入图片描述

1.2 GetMessageResult类

查询消息是到ConsumerQueue中拿的数据ConsumerQueueData,每个ConsumerQueueData都是20个字节,ConsumerQueueData存了每个消息的物理offset(8字节)、消息的size(4字节)和tagCode(8字节),有了ConsumerQueueData之后就可以到CommiLog里通过getMessage获取一条消息,该消息由SelectMappedBufferResult封装(CommitLog里由MappedFileQueue管理内存映射文件,管理着MappedFile组成的List,消息的归属者就是MappedFile),SelectMappedBufferResult对象该消息归属的MappedFile是谁和byteBuffer。为什么要存该消息归属的MappedFile是谁呢?因为MappedFile对外提供一次查询后refcount会执行++操作,查询出来的结果最终会导入到Response事务body里,此时GetMessageResult会调用release方法,该方法调用会执行GetMessageResult对象里的messageMappedList方法的release方法,该方法会让MappedFile的refCount执行–操作,refcount归零后就说明该MappedFile没人用了,占用的MappedByteBuffer内存(堆外内存)就会释放
在这里插入图片描述

1.2 getMessage方法的流程

如下图,RunningFlag有好多位在下一篇看源码的时候再去探究。
获取到的ConsumerQueue从消费队列映射表里拿,ConsumerQueue里存的是MappedFileQueue,MappedFileQueue里有MappedFile组成的List,MappedFile大小是固定的,20*30w的大小,MappFile里存了ConsumerQueueData。
检查ConsumeQueue是否可满足本次pull请求的offset的offset是以消息为单位,不是ConsumerQueueData里的offset。检查通过才能继续往下走。
在这里插入图片描述
上图中的检查状态的状态码在前几篇内容里已经讲到了,这里再列出来,如下:
在这里插入图片描述
查询出来数据后就是处理数据的逻辑,在下图可以看出,出来数据是在一个循环里,当16000字节满了(处理800个ConsumerQueueData)之后跳出循环。返回true才跳出循环

在这里插入图片描述

为什么计算冷数据的逻辑是CommitLog的最大物理偏移量-offsetPy大于系统内存的40%呢?
当前正在顺序写的mappedFile是固定写死的1G,运行时间非常长,MQ发送的消息非常多时,当内存不够时,需要释放内存,其他模块占了0.8g,JVM有4g,CommitLog占了大约3.2g,3.2/8*100%=40%,当然这只是评估的规则不是准确情况。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值