RocketMq5.0 任意延迟时间 TimerMessageStore 源码解析
TimerMessageStore 简略介绍
- 延迟队列
rmq_sys_wheel_timer - 指定时间的延迟消息。会先投递到
rmq_sys_wheel_timer队列中 - 然后由
TimerMessageStore消费队列数据,将数据消费到timerWheel使用时间轮算法,实现秒级任务
TimerMessageStore 操作的文件
store\consumequeue\rmq_sys_wheel_timer从队列中读取消息, 提取数据存到timerlog与timerwheel中store\checkpoint对应TimerMessageStore#timerCheckpointlastReadTimeMs上次消费的时间节点lastTimerLogFlushPos最后刷新 log的 poslastTimerQueueOffset最后一次消费的队列节点masterTimerQueueOffset主 Broker 的队列消费节点
store\timerwheel时间轮,内由Slot组成 结构如下timeMs消息到达时间firstPos开始的 poslastPos结束的 pos 在 timerLog 中读取数据, 后面会讲具体逻辑num消息数量magicno use now, just keep it
store\timerlog对应TimerMessageStore#timerCheckpoint
里边也是由多个mappedFile组成。
主要是存储原msg的数据,
因为从rmq_sys_wheel_timer消费了之后,
会存到timerwheel与timerlog中
TimerMessageStore 启动
- enqueueGetService.start();
- enqueuePutService.start();
- dequeueWarmService.start();
- dequeueGetService.start();
- timerFlushService.start();
- dequeueGetMessageServices[getThreadNum].start();
- dequeuePutMessageServices[getThreadNum].start();
深入 TimerMessageStore 之 TimerEnqueueGetService
TimerMessageStore.this.enqueue默认 100毫秒执行一次- 从 消息队列
rmq_sys_wheel_timer消费数据 ps:currQueueOffset从checkpoint读取出来的 - 将消费出来的数据, 封装成 TimerRequest 投入到
enqueuePutQueue中 currQueueOffset + 1进入下一个循环 消费下一个 offset 节点
深入 TimerMessageStore 之 TimerEnqueuePutService
- 消费
enqueuePutQueue中的数据 shouldRunningDequeue && req.getDelayTime() < currWriteTimeMs检查消费的消息是否已到达投递时间。- 到达时间。投递到
dequeuePutQueue.put(req);中 - 消息未到达时间
doEnqueue->timerWheel.getSlot(delayedTime)获取延迟时间插槽。- 构建
ByteBuffer投入timerLog中数据结构为: - |消息大小|前一个节点的pos|magic|log写入时间|延迟时间|offsetPy|sizePy|realTopic|0
timerLog.append返回插入位置 ret- 构建
timerWheel|消息到达时间戳|firstPos|ret (timerLog.append返回位置)| 消息数量| 0|
- 到达时间。投递到
深入 TimerMessageStore 之 TimerDequeueGetService
- 消费
timerWheel中的数据 - 根据
currReadTimeMs来获取timerWheel插槽数据currReadTimeMs初始化的时候timerCheckpoint.getLastReadTimeMs()读取的是上次最后消费的数据- 假设broker 宕机了一段时间。那么
currReadTimeMs会按照上一次宕机的时间开始搜寻数据, 这样子宕机消息也不会丢失。会在启动的那段时间被投递出去 currReadTimeMs在moveReadTime方法中会自增
timerWheel.getSlot(currReadTimeMs);读取插槽数据long currOffsetPy = slot.lastPos;读取插槽属性, 最后一个pos节点timerLog.getWholeBuffer(currOffsetPy)根据currOffsetPy获取SelectMappedBufferResult- 从
timerLog的SelectMappedBufferResult中获取数据。prevPos上一个节点数据enqueueTime放入 timerLog 的时间delayedTime消息到达时间戳offsetPycommitLog的数据位置sizePycommitLog的数据大小
- 构建
TimerRequest讲消息投递到dequeueGetQueue中 currOffsetPy = prevPos将位置移动到前一个,进行遍历
深入 TimerMessageStore 之 TimerDequeueGetMessageService
- 默认有三个
TimerDequeueGetMessageService实例同时消费dequeueGetQueue getMessageByCommitOffset从commitLog中读取原投递的消息数据- 读取
uniqkey判断不在deleteList中的时候 将消息投递到dequeuePutQueue中去
深入 TimerMessageStore 之 TimerDequeuePutMessageService
- 默认有三个
TimerDequeuePutMessageService实例同时消费dequeuePutQueue convert(tr.getMsg(), tr.getEnqueueTime(), needRoll(tr.getMagic()));将消息转换成原始的 topic 消息,清除无用属性doPut->messageStore.putMessage(message)将消息投递到指定messageQueue中
TimerFlushService
timerLog刷盘timerWheel刷盘timerCheckpoint刷盘
TimerMessageStore 初始化加载源码
timerLog.load()加载文件timerMetrics.load加载文件recover->recoverAndRevise(lastFlushPos, true)ps: (用于timerWhel跟timerLog的数据保持一致刷新)lastFlushPos最后一次刷盘的位置, 其实最终是拿到timerlog -> mappedFile的第几个文件- 遍历这个
mappedFile的数据 timerWheel.reviseSlot修改插槽数据。 检查这个时间的插槽是否已经有填充数据。- 如果有的话,刷新
lastPos(顺序遍历。这里最终还是会是最后一个 lastPos) - 如果不存在插槽数据 则插入插槽数据
putSlot
- 如果有的话,刷新
reviseQueueOffset(processOffset);读取timerLog最后一个数据, 为了校验最后一个数据是否正常,是否能读取到消息。- 确认
currQueueOffset数据 - 确认
currReadTimeMs数据
RocketMq5.0 任意延迟时间 TimerMessageStore 源码解析的更多相关文章
- abp vnext2.0核心组件之.Net Core默认DI组件切换到AutoFac源码解析
老版Abp对Castle的严重依赖在vnext中已经得到了解决,vnext中DI容器可以任意更换,为了实现这个功能,底层架构相较于老版abp,可以说是进行了高度重构.当然这得益于.Net Core的D ...
- EventBus3.0源码解析
本文主要介绍EventBus3.0的源码 EventBus是一个Android事件发布/订阅框架,通过解耦发布者和订阅者简化 Android 事件传递. EventBus使用简单,并将事件发布和订阅充 ...
- solr&lucene3.6.0源码解析(四)
本文要描述的是solr的查询插件,该查询插件目的用于生成Lucene的查询Query,类似于查询条件表达式,与solr查询插件相关UML类图如下: 如果我们强行将上面的类图纳入某种设计模式语言的话,本 ...
- solr&lucene3.6.0源码解析(三)
solr索引操作(包括新增 更新 删除 提交 合并等)相关UML图如下 从上面的类图我们可以发现,其中体现了工厂方法模式及责任链模式的运用 UpdateRequestProcessor相当于责任链模式 ...
- Heritrix 3.1.0 源码解析(三十七)
今天有兴趣重新看了一下heritrix3.1.0系统里面的线程池源码,heritrix系统没有采用java的cocurrency包里面的并发框架,而是采用了线程组ThreadGroup类来实现线程池的 ...
- Masonry1.0.2 源码解析
在了解Masonry框架之前,有必要先了解一下自动布局的概念.在iOS6之前,UI布局的方式是通过frame属性和Autoresizing来完成的,而在iOS6之后,苹果公司推出了AutoLayout ...
- Retrofit2.0源码解析
欢迎访问我的个人博客 ,原文链接:http://wensibo.net/2017/09/05/retrofit/ ,未经允许不得转载! 今天是九月的第四天了,学校也正式开学,趁着大学最后一年的这大好时 ...
- 04、NetCore2.0下Web应用之Startup源码解析
04.NetCore2.0Web应用之Startup源码解析 通过分析Asp.Net Core 2.0的Startup部分源码,来理解插件框架的运行机制,以及掌握Startup注册的最优姿势. - ...
- Android事件总线(二)EventBus3.0源码解析
1.构造函数 当我们要调用EventBus的功能时,比如注册或者发送事件,总会调用EventBus.getDefault()来获取EventBus实例: public static EventBus ...
- 简单理解 OAuth 2.0 及资料收集,IdentityServer4 部分源码解析
简单理解 OAuth 2.0 及资料收集,IdentityServer4 部分源码解析 虽然经常用 OAuth 2.0,但是原理却不曾了解,印象里觉得很简单,请求跳来跳去,今天看完相关介绍,就来捋一捋 ...
随机推荐
- 巧用Nginx配置解决跨域问题
页面nginx配置 1,前端页面放在域名根目录,比如,http://www.xuecheng.com/ ,对应的nginx配置: #门户 location / { alias D:/Z_lhy/Spr ...
- FreeSWITCH添加iLBC编码及转码
操作系统 :CentOS 7.6_x64 FreeSWITCH版本 :1.10.9 一.安装ilbc库 从第三方库里下载指定版本: git clone https://freeswitch.org/s ...
- 谈谈selenium中的clear后输入内容异常的处理
谈谈selenium中的clear后输入内容异常的处理 案例 在线考试项目的登录:http://124.223.31.21:9097/#/ 代码 from selenium import webdri ...
- win10环境下 VMware Workstation Pro 安装centos7无法上网
一.安装centos7 网上类似的教程太多了,我就不一一写了,提供两个网址,先按照教程安装 VMware Workstation Pro ,秘钥在第二个链接里面(亲测可用), 安装完VMware在根据 ...
- Maven的大概了解及总结setting和pom
前言:项目中经常要用到Maven,从来也没有配置过,直到当人问到Maven是干什么的,是怎么管理项目的?一头雾水,所以写了这篇博客,首先附上百度百科的词条: Maven项目对象模型(POM),可以通过 ...
- [OpenCV-Python] 14 几何变换
文章目录 OpenCV-Python:IV OpenCV中的图像处理 14 几何变换 14.1 扩展缩放 14.2 平移 14.3 旋转 14.4 仿射变换 14.5 透视变换 OpenCV-Pyth ...
- 2020-11-12:java中as-if-serial语义和happen-before语义有什么区别?
福哥答案2020-11-12: as-if-serial语义单线程执行结果不被改变.happen-before语义正确同步的多线程执行结果不被改变.***这道题网上已经说烂了,就不必重复了.[happ ...
- 2022-02-04:组合总和 Ⅳ。 给你一个由 不同 整数组成的数组 nums ,和一个目标整数 target 。请你从 nums 中找出并返回总和为 target 的元素组合的个数。 题目数据保证
2022-02-04:组合总和 Ⅳ. 给你一个由 不同 整数组成的数组 nums ,和一个目标整数 target .请你从 nums 中找出并返回总和为 target 的元素组合的个数. 题目数据保证 ...
- wmi搜集一台计算机的硬件信息
作用: Python搜集一台计算机的硬件信息,借助模块:wmi,这个模块只支持window操作系统. 安装: pip install wmi 导入: import wmi 实例 c = wmi.WMI ...
- https 原理与实践
https 原理与实践 经典三问,是什么,为什么,怎么做? 是什么 是一种http的安全协议,在tcp ip网络模型里,http应用层是在tcp 传输层之上的,https协议规定了在tcp传输层之上还 ...