rocketmq的消费者源码解读七(并发消费)

11)并发消费

分两部分,一个是定时任务清除客户端本地的过期数据,一个是消费拉取到的消息;

11.1)消费者启动时会清理processQueue中的过期消息

DefaultMQPushConsumerImpl#start()方法中会执this.consumeMessageService.start()方法,其中会执行一个调度任务,延迟15分钟,每隔15分钟执行ConsumeMessageConcurrentlyService#cleanExpireMsg方法,该方法会遍历processQueueTable,执行每个ProcessQueue#cleanExpireMsg方法;清理processQueue上超过了15分钟未被消费的数据;
1)权限控制
若是顺序直接return,若msgTreeMap中消息数大于或等于16,则最多遍历16次;
2)判断最大值是否小于15分钟
拿到msgTreeMap的读锁,判断msgTreeMap中的第一条消息的消费开始时间距离当前时间是否超过15分钟,若没有,则表示最大值都小于15分钟,故整个msgTreeMap中所有数据的消费时间都不会超过15分钟,则跳出循环,退出方法;若第一条消息的消费时间大于15分钟,则取出该条消息保存至msg,准备回退;
3)回退与删除
3.1)执行 pushConsumer.sendMessageBack方法,回退刚才的msg,并设定延迟级别为3;
3.2)获取msgTreeMap的写锁,判断msg的offset是否还是msgTreeMap的firstKey,如果不相等,则表示在消息回退期间,该条消息被消费任务成功消费掉,导致该条消息从msgTreeMap中移走,firstKey发生变化,此时不能删除该条msg;只有在消息回退期间,该条消息没有被消费任务成功消费,接下来才能将该条msg从msgTreeMap中删除,此时当再次循环处理时,firstKey已发生变化;

11.2)提交消费任务以及任务运行

在两种场景下会提交消费任务,当客户端发送拉取消息的请求后,broker端处理后,返回数据给客户端,此时客户端会提交消费任务;另外当消费失败,并且回退也失败了,此时会再次提交消费任务;
由提交消费任务由方法ConsumeMessageConcurrentlyService#submitConsumeRequest执行,上接8.2.1.4小节,客户端从broker端成功拉取到消息后,准备提交至消费线程池进行消费;

11.2.1)实例化ConsumeRequest

封装了List,processQueue,messageQueue;

11.2.2)consumeExecutor.submit

入参为ConsumeRequest实例;ConsumeRequest继承了Runnable;接着进入ConsumeRequest#run方法中;获取消息提交的规格consumeBatchSize,默认为1;消息数量小于规格大小,则直接封装成consumeRequest提交至消费任务线程池,若消息数量大于规格大小,则每次封装规格数量的消息至consumeRequst中,再提交至消费任务线程池;

11.2.2.1)processQueue是否为dropped状态
11.2.2.2)重试消息恢复原主题

执行DefaultMQPushConsumerImpl#resetRetryAndNamespace方法,遍历msg,若为重试消息,则恢复原主题,判断重试消息的条件是消息的RETRY_TOPIC属性值不为null,则用原主题值替换主题%RETRY%groupName属性的值,即恢复原主题;

11.2.2.3)设置每条消息消费开始时间

在清除过期消息的时候,会用到;

11.2.2.4)执行listener.consumeMessage方法
执行业务逻辑,返回三种状态CONSUME_SUCCESS,RECONSUME_LATER,null,若为null,则设置为RECONSUME_LATER;
11.2.2.5)processConsumeResult

如果在业务消费过程中,当前messageQueue被分配给了其他consume或者消费者退出,则无需处理消费结果,直接退出run方法,否则执行ConsumeMessageConcurrentlyService#processConsumeResult方法;该方法主要完成以下任务

11.2.2.5.1)消费结果为CONSUME_SUCCESS

准备从processQueue中移除该条消息;此时设置ackIndex为List的长度减1(长度和容量不是一回事,长度指实际元素个数);接着会以ackIndex+1为起点,遍历List,由于条件不满足所以此时直接退出for循环,不会进行遍历;

11.2.2.5.2)消费结果为RECONSUME_LATER,执行消息回退
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

orcharddd_real

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值