RocketMQ之DefaultPushConsumer

DefaultMQPushConsumer消息链路

  1. DefaultMQpushConsumer#start方法调用DefaultMQpushConsumerImpl#start方法,接着内部调用MQClientInstance#start方法,接着调用RebalanceService#start方法。

  2. RebalanceService#start方法开启一个线程,执行本类中的runnable#run方法。run方法中调用MQClientInstance#doRebalance方法,这个方法阻塞20秒,循环调用。

  3. MQClientInstance#doRebalance方法中接着调用DefaultMQpushConsumerImpl#doRebalance方法。

  4. DefaultMQpushConsumerImpl#doRebalance中接着调用RebalanceImpl#doRebalance方法。

  5. RebalanceImpl#doRebalance方法接着调用本类方法rebalanceByTopic,根据负载均衡分配策略获取当前消费者组对应的messageQueues,接着调用本类方法updateProcessQueueTableInRebalance。
    在这里插入图片描述

  6. RebalanceImpl#updateProcessQueueTableInRebalance方法中。①内部属性processQueueTable维护messageQueue与processQueue的关系。②调用broker获取messagQueue的消息处理偏移量。每个队列封装参数为PullRequest(里面包含消费者组名称,下一个消息的偏移量,messageQueue,processQueue),调用本地方法dispatchPullRequest传入参数PullRequests。

  7. RebalanceImpl#dispatchPullRequest方法。这是一个抽象方法,实现在RebanlancePushImpl中。在RebanlancePushImpl#dispatchPullRequest中,for循环遍历PullRequests,调用DefaultMQpushConsumerImpl#executePullRequestImmediately(pullRequest)方法执行。
    在这里插入图片描述

  8. DefaultMQpushConsumerImpl#executePullRequestImmediately方法中调用MQClientInstance的属性对象pullMessageService的方法executePullRequestImmediately,将pullReuqest存到到pullMessageServcie的内部属性队列pullMessageQueue中,这是一个LinkedBlockingQueue队列。
    在这里插入图片描述在这里插入图片描述

  9. PullMessageServcie#start方法,开启线程执行本类中的run方法。run方法中①通过take获取pullMessageQueue中的pullRequest,②调用本地的pullMessage方法进行处理。

在这里插入图片描述
在这里插入图片描述
10. PullMessageServcie#pullMessage方法,通过MQClientInstance获取到consumer,我这里用的是DefaultMQpushConsumerImpl,调用DefaultMQpushConsumerImpl#pullMessage(pullRequest)方法。
11. DefaultMQpushConsumerImpl#pullMessage方法。①获取pullRequest中的messageQueue的主题关联的订阅者。②定义回调方法PullCallback。回到方法中,如果从broker拉取消息成功,会将消息放入到processQueue的msgTreeMap中③调用pullAPIWrapper#pullKernelImpl方法拉取消息。
在这里插入图片描述
12. PullAPIWrapper#pullKernelImpl方法,调用MQClientInstance的属性类MQClientAPIImpl的pullMessage方法。
在这里插入图片描述
13. MQClientAPIImpl#pullMessage方法。调用remotingCLient发送netty消息到broker。拿到消息后,调用步骤11中定义的PullCallback方法。
14. DefaultMQpushConsumerImpl#PullCallback方法,将消息封装到ConsumeRequest,提交到MessageListenerConcurrently的任务线程池中consumerExecutor。
在这里插入图片描述
15. ConsumeRequest本身实现runnable接口,实现run方法。ConsumeRequest是MessageListenerConcurrently的内部类。①调用消费者的监听器,将消息传入。②根据监听器类处理响应status,处理响应结果。
在这里插入图片描述 在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

DefaultMQPushConsumer消息处理类

  消息处理类ConsumeMessageService。
   DefaultMQPushConsumer–>DefaultMQPushConsumerImpl#start(),根据注册的监听器类型实例化ConsumeMessageService。
  (1) 注册的监听器是:MessageListenerOrderly,对应实例化的消息处理类:ConsumeMessageOrderlyService
   (2) 注册的监听器是:MessageListenerConcurrently,对应实例化的消息处理类: ConsumeMessageConcurrentlyService
  ConsumeMessageConcurrentlyService:
  属性中包含了消费者配置的监听类messageListener,defaultMQPushConsumer,defaultMQPushConsumerImpl,consumeRequestQueue(请求阻塞队列)
。初始化了三个线程池。
  (1)消息处理线程池consumerExecutor,线程池的核心线程,最大线程通过参数配置,setConsumeThreadMin,setConsumeThreadMax,主要处理正常接收到的消息。
  (2) 还有两个定时执行线程池,一个用来执行推迟消费的消息,一个用来定期清理超时消息(15分钟)。

DefaultMQPushConsumer消息偏移量

  消费者有两种模式,集群模式和广播模式。

广播模式

  广播模式,偏移量的处理类offsiteStore的实现类LocalFileOffsetStore。广播模式的偏移量是保存到本地。可以通过参数【rocketmq.client.localOffsetStoreDir】进行配置。
  OffsetStore的load方法读取上面的文件,如果读取失败或者文件内容为空,就会读取备份文件,路径是上面的文件名后面加.bak。这个load方法读取这个json文件,然后把内容读取到LocalFileOffsetStore类的offsetTable(ConcurrentHashMap)这个数据结构。
  在拉取消息的时候,首先会封装PullRequest请求,PullRequest中nextOffset参数需要从offsetTable中获取。
  MQClientInstance的start方法中会开启一个定时任务,默认时间是5秒,每5秒执行一次持久化,将offsetTable持久化到 本地文件。写文件时有以下几步:
1. 首先把内容写入到offsets.json.tmp文件。
2. offsets.json内容备份到offsets.json.bak。
3. 删除offsets.json文件。
4. 把offsets.json.tmp改名为offsets.json。

   总结:广播模式下,偏移量保存在消费者本地服务器。
在这里插入图片描述

集群模式

   集群模式,偏移量的处理类offsiteStore的实现类RemoteBrokerOffsetStore
   集群模式下,偏移量是从Broker端获取,所以客户端RemoteBrokerOffsetStore中的load方法没有内容,是一个空方法。
在这里插入图片描述
   集群模式下,偏移量保存在Broker服务器上。默认路径在/home/${user}/store/config/consumerOffset.json
   集群模式下,消费者端也会定时持久化offsetStore,不过集群模式下这个方法会上报消费点到Broker服务上。Broker服务接收到请求会保存到本地的offsetTable本地缓存中,Broker服务启动也会开启一个定时任务,默认每5秒持久化offsetTable到磁盘文件。
   RebalanceImpl的updateProcessQueueTableInRebalance在拉取消息的时候。都需要先计算nextOffset,这个计算方法是一个抽象方法,由其子类实现。我们就看看push里面的实现RebalancePushImpl里面的实现。 在这里插入图片描述

  1. 首先获取DefaultMQPushConsumer里面的配置consumerFromWhere
  2. 获取对应的offsetStore。我们用的集群模式,这里是RemoteBrokerOffsetStore
  3. 通过不同的类型,走不通的逻辑获取偏移量。我这里配置的是CONSUME_FROM_MAX_OFFSET,是通过RemoteBrokerOffsetStore的readOffset获取偏移量。参数类型是ReadOffsetType.READ_FROM_STORE
@Override
public long computePullFromWhereWithException(MessageQueue mq) throws MQClientException {
    long result = -1;
    // 1. 获取DefaultMQPushConsumer里面的配置consumerFromWhere。
    final ConsumeFromWh
  • 12
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
RocketMQPushConsumer是一种消息消费者模式,它是基于拉取模型的实现。尽管消息消费被称为Push,但实际上仍然是通过拉取的方式来获取消息。\[1\]在RocketMQ中,消费者有两种模式,一种是push模式,另一种是pull模式。在push模式中,当服务端有消息时,将消息推送到客户端。而在pull模式中,客户端需要不断轮询请求服务端来获取新的消息。\[3\]不过,无论是push模式还是pull模式,实际上都是采用消费端主动拉取的方式,即consumer轮询从broker拉取消息。\[3\]在PushConsumer中,轮询过程被封装在内部,并通过注册MessageListener监听器来消费消息。当消息到达时,会唤醒MessageListener的consumeMessage()方法来进行消费,给用户一种消息被推送过来的感觉。\[3\]而在PullConsumer中,用户需要自己编写获取消息的逻辑,首先通过打算消费的Topic获取MessageQueue的集合,然后遍历MessageQueue集合,针对每个MessageQueue批量获取消息,一次取完后记录该队列下一次要取的开始offset,直到取完了再切换到另一个MessageQueue。\[3\]所以,PushConsumerRocketMQ中用于实现push模式消息消费的一种消费者。 #### 引用[.reference_title] - *1* [RocketMQ实战-初探PushConsumer限流机制实现原理](https://blog.csdn.net/Huangjiazhen711/article/details/127746551)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [rocketmq源码-consumer拉取消息(push模式)](https://blog.csdn.net/CPLASF_/article/details/128311025)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [rocketMQ之consumerpush和pull模式](https://blog.csdn.net/qq_26896085/article/details/104958768)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值