RocketMQ存储篇——Config文件以及执行延迟消息的线程服务
来源:互联网 发布:cbox网络电视去广告版 编辑:程序博客网 时间:2024/05/19 01:58
在$HOME\store\config目录下面存储各类config文件,包括:consumerOffset.json、delayOffset.json、subscriptionGroup.json、topics.json四类config文件。
topics.json文件由TopicConfigManager类解析并存储;存储每个topic的读写队列数、权限、是否顺序等信息。
consumerOffset.json文件由ConsumerOffsetManager类解析并存储;存储每个消费者Consumer在每个topic上对于该topic的consumequeue队列的消费进度;
delayOffset.json文件由ScheduleMessageService类解析并存储;存储对于延迟主题SCHEDULE_TOPIC_XXXX的每个consumequeue队列的消费进度;
subscriptionGroup.json文件由SubscriptionGroupManager类解析并存储;存储每个消费者Consumer的订阅信息。
各类图机构如下:
1 ScheduleMessageService执行延迟消息
该类除了解析并存储delayOffset.json文件之外,还有一个重要的任务,就是定时执行延迟消息的任务。
在load方法中,将这些级别("1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h")的延时存入延迟级别delayLevelTable:ConcurrentHashMap<Integer /* level */, Long/* delay timeMillis */>变量中,例如1s的kv值为1:1000,5s的kv值为2:5000,key值依次类推;每个延迟级别即为一个队列。
在Broker启动时调用ScheduleMessageService.start方法,在该方法处理两件事:一、每个延迟队列增加定时器;二、设置定时任务将延迟进度刷盘。
为每个延迟级别设置一个定时器。遍历delayLevelTable列表,key值为level,并以level从offsetTable中获取该级别的队列消费进度offset。以level、offset为参数初始化DeliverDelayedMessageTimerTask对象,并存入定时器中,在1秒之后在调用该对象的run方法。
延迟消费逻辑就在DeliverDelayedMessageTimerTask对象的run方法中。在该方法中调用executeOnTimeup方法,若该方法抛出异常,则重新初始化DeliverDelayedMessageTimerTask对象并放入定时器中,在10秒之后重新执行该对象。其中executeOnTimeup方法的业务逻辑如下:
1)调用DefaultMessageStore对象的findConsumeQueue(String topic, int queueId)方法获取对应的ConsumeQueue对象;其中topic等于"SCHEDULE_TOPIC_XXXX";queueId等于延迟级别level减1;
2)以offset偏移量为参数调用ConsumeQueue对象的getIndexBuffer方法获取consumequeue的数据;若未获取到ConsumeQueue对象则以offset、level为参数初始化DeliverDelayedMessageTimerTask对象并放入定时器中,100毫秒之后再重新执行;
3)从consumequeue的数据中逐个继续每个消息单元,根据每个消息单元的tagsCode检查延迟时间是否已经到了,以tagsCode存储的时间戳减去当前时间戳;
3.1)若大于零则表示延迟时间未到,则以该数据开始偏移量为offset,对应的level为参数初始化DeliverDelayedMessageTimerTask对象,并且在该时间差额之后再次调用该对象的run方法;然后更新ScheduleMessageService.offsetTable变量中相应延迟级别的offset值;
3.2)若小于等于零则表示延迟时间已经到了。首先以解析出来的物理偏移量commitLogOffset和消息大小size为参数调用DefaultMessageStore对象的lookMessageByOffset(long commitLogOffset, int size)方法;然后将该方法返回的MessageExt对象转换成MessageExtBrokerInner对象,其中,主要是将真实的topic和queueId从消息的properties中取出并设置到给MessageExtBrokerInner对象中;再调用DefaultMessageStore对象的putMessage(MessageExtBrokerInner msg)方法进行消息写入。若写入消息成功,则继续解析后面的消息单元,然后重复执行第3步;否则以该数据开始偏移量为offset、对应的level为参数初始化DeliverDelayedMessageTimerTask对象并放入定时器中,在10秒之后重新执行;并且更新ScheduleMessageService.offsetTable变量中相应延迟级别的offset值;
4)在第3步中对获取到的consumequeue数据逐个解析完成之后,将上述consumequeue数据的最后一个消息读取偏移量之后的一个消息读取偏移量(offset+consumequeue消息中的消息单元个数)作为nextoffset、对应的level为参数初始化DeliverDelayedMessageTimerTask对象并放入定时器中,100毫秒之后再重新执行;
2 收到发送消息时创建topic的配置信息(createTopicInSendMessageMethod)
调用TopicConfigManager.createTopicInSendMessageMethod(final String topic, final String defaultTopic,final String remoteAddress, final int clientDefaultTopicQueueNums, final int topicSysFlag)方法进行Topic配置的创建。大致逻辑如下:
1、以参数topic从TopicConfigManager.topicConfigTable中获取该topic的配置信息对象TopicConfig;若获取到了则直接返回该对象;否则创建一个新的配置对象并存入topicConfigTable变量中;
2、该topic不存在,则以参数defaultTopic从TopicConfigManager.topicConfigTable中获取该topic的配置信息对象TopicConfig,该参数在Producer发送信息时默认为"TBW102",而该topic在Broker启动时会自动创建;
3、用topic来初始化新的TopicConfig对象,并用以defaultTopic获取到的TopicConfig对象的其他参数来初始化新创建的TopicConfig对象;
4、将新创建的TopicConfig对象以topic为key值存入TopicConfigManager.topicConfigTable变量中,并且更新dataVersion值;
5、然后将topicConfigTable变量值持久化到topics.json物理文件中。
3 根据GroupName查找订阅组信息(findSubscriptionGroupConfig)
调用SubscriptionGroupManager.findSubscriptionGroupConfig(String GroupNmae)方法获取订阅信息。大致步骤如下:
1、以GroupNmae从SubscriptionGroupManager.SubscriptionGroupTable变量中获取订阅信息SubscriptionGroupConfig对象;若不为空则直接返回该对象;
2、若为空,表示还没有该订阅信息,再检查Broker是否运行自动创建订阅组(由配置参数autoCreateSubscriptionGroup设置,默认为true)。若不允许则直接返回null;若允许则首先以GroupName为参数创建SubscriptionGroupConfig对象,并存入SubscriptionGroupTable变量中;然后更新SubscriptionGroupManager的dataversion值;再将SubscriptionGroupManager的内容持久化到subscriptionGroup.json文件中;最后返回该新创建的SubscriptionGroupConfig对象;
4收到消费失败时的回传消息时创建topic的配置信息(createTopicInSendMessageBackMethod)
调用TopicConfigManager.createTopicInSendMessageBackMethod(String topic, int clientDefaultTopicQueueNums, int perm, int topicSysFlag)方法进行Topic配置的创建。大致逻辑如下:
1、以参数topic从TopicConfigManager.topicConfigTable中获取该topic的配置信息对象TopicConfig;若获取到了则直接返回该对象;否则创建一个新的配置对象并存入topicConfigTable变量中;
2、以该方法的入参初始化TopicConfig对象,并以topic为key值存入TopicConfigManager.topicConfigTable变量中,并且更新dataVersion值;
3、然后将topicConfigTable变量值持久化到topics.json物理文件中。
- RocketMQ存储篇——Config文件以及执行延迟消息的线程服务
- RocketMQ存储篇——事务消息相关的文件
- RocketMQ——Consumer篇:PUSH模式下拉取消息服务的线程(PullMessageService)
- RocketMQ的消息存储
- RocketMQ消息延迟配置
- RocketMQ存储篇——整体结构以及MappedFile讲解
- RocketMQ源码解析-Broker的消息存储
- Android 调用UI线程以及延迟执行
- RocketMQ源码学习--消息存储篇
- RocketMQ(5)——消息文件过期原理
- RocketMQ存储篇——MapedFileQueue
- RocketMQ存储篇——CommitLog
- RocketMQ存储篇——Consumequeue
- RocketMQ——顺序消息
- RocketMQ消息队列服务部署
- RocketMQ源码分析----消息存储
- rocketmq 延迟队列的实现
- rocketmq 延迟队列的实现
- Ajax 发送WebAPI
- 487-3279 POJ-1022【前导0~思维漏洞】
- 杰克沃顿大神的 rxbinding框架
- 希腊字母表及读音
- Python collections模块总结
- RocketMQ存储篇——Config文件以及执行延迟消息的线程服务
- Codeblocks编辑器的设置
- 2007 NOIP 统计数字
- 请求JSON格式文件文件问题
- 背包九讲
- UNP 基于Epoll复用的回射服务器性能测试
- AngularJs:Service、Factory、Provider依赖注入使用与区别
- iOS绘图框架CoreGraphics分析
- pageX、pageY及父元素的页面坐标使提示框跟随鼠标移动