RocketMQ 源码分析 06 消息消费01

消息消费方式 : 拉取、推送

消费者启动流程

1.初始化MQClientInstance

2.初始化消息进度 : 集群模式,消费进度保存在Broker上;广播模式,消费进度保存在消费端

 

从何处开始消费,可选值:
1)CONSUME_FROM_LAST_OFFSET:上一次消费偏移量
2)CONSUME_FROM_FIRST_OFFSET:从头开始
3)CONSUME_FROM_TIMESTAMP:从某个时间点开始

消费进度存储
其实现类为:OffsetStore offsetStore。消费者需要记录消息消费的进度:
1)广播模式:广播模式由于每个消费者都需要消费消息,故消息的进度(最后消费的偏移量可以保存在本地)。
2)集群模式:由于集群中的消费者只要一个消费消息即可,故消息的消费进度,需要保存在集中点,故 RocketMQ存储在Broker所在的服务器。
广播消费偏移量 保存在本地; 集群模式,消费偏移offset保存在broker的机器

 消息消费过程

消息的消费过程,就是从服务器拉取,然后消费者进行消费,再根据业务反馈是否成功消费来推动消费进度,也就是消息的消费进度并不是保存在服务端(比如 commitlog 文件中),而是保存在消费端(可以是本地(广播模式)、broker端(集群模式))具体的代码实现:

2.2 消息消费者启动关键流程

1) 构建 RebalanceImpl

2)PullAPIWrapper 对象构建

3)消费进度加载

5)MQClientInstance 启动,进入消息消费

6. 每隔30S尝试更新主题路由信息

7. 每隔30S 进行Broker心跳检测

8. 默认每隔5秒持久化ConsumeOffset

一个应用程序,一个消费组,只需要一个DefaultMQPushConsumerImpl,,在一个应用中,使用多线程创建多个

消费者,尝试去消费同一个组,没有效果,只会有一个消费者在消费。

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

DefaultMQPushConsumerImpl pullMessage 关键代码

 

1、首先获取PullRequest的 处理队列ProcessQueue,然后更新该消息队列最后一次拉取的时间。

2、如果消费者 服务状态不为ServiceState.RUNNING,或当前处于暂停状态,默认延迟3秒再执行(PullMessageService.executePullRequestLater)

3、流量控制,两个维度,消息数量达到阔值(默认1000个),或者消息体总大小(默认100m)

4、获取主题订阅信息

5、如果是集群消费模式,从内存中获取MessageQueue的commitlog偏移量。

6、构建拉取消息系统Flag: 是否支持comitOffset,suspend,subExpression,classFilter

7、根据brokerName, brokerId从MQClientInstance中获取broker地址

接下来,以异步调用为例,分析拉取到消息后的回调处理逻辑。
代码入口:PullCallback pullCallback = new PullCallback(),见DefaultMQPushConsumerImpl 288行
1、首先对PullResult进行处理,主要完成如下3件事:

    1)对消息体解码成一条条消息

    2)执行消息过滤

    3)执行回调

2、根据拉取结果分别采取不同的策略

1)拉取到消息,首先放入到处理队列中;然后是消费消息服务提交

第一步,将消息放入消费队列中:就是将拉取的消息,放入到ProcessQueue的msgTreeMap容器中。

第二步,消费消息服务提交

该方法重点已经标明,如果此次拉取的消息条数大于ConsumeMessageBatchMaxSize,则分批消费

线程池的常驻线程数:consumeThreadMin
线程池的最大线程数:consumeThreadMax
线程池中的线程名:ConsumeMessageThread_
这里就明确了一个点,一个消费者非顺序消费者,内部使用一个线程池来并非消费消息,一个线程一批次最大处理consumeMessageBatchMaxSize条消息。
再总结一下非顺序消费(并非消费)的主要思路:
1、将待消费的消息存入ProcessQueue中存储,并执行消息消费之前钩子函数
2、修改待消费消息的主题(设置为消费组的重试主题)
3、分页消费(每次传给业务消费监听器的最大数量为配置的
sconsumeMessageBatchMaxSize
4、执行消费后钩子函数,并根据业务方返回的消息消费结果(成功,重试)【ACK】确认信息,然后更新消息进度,从ProcessQueue中删除相应的消息

8.如果从节点数据包含下一次拉取的偏移量,设置下一次拉取任务的brokerId

9.如果commitLog 标记可用,并且当前节点为主节点,则更新消息消费进度

 

 

 

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

RocketMQ的push模式

我们都知道RocketMQ在消费端有push和pull两种模式,pull模式需要我们手动调用consumer拉消息,而push模式则只需要我们提供一个listener即可实现对消息的监听,而实际上,RocketMQ的push模式是基于pull模式实现的,它没有实现真正的push。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值