17、DefaultMQPushConsumer消费者发起拉取消息请求源码

下面我们来介绍DefaultMQPushConsumer消费者如何拉取消息的源码,主要步骤可以分为三部分:
1、consumer发送拉取消息请求。
2、broker处理拉取消息请求。
3、consumer接收请求响应。

1 PullMessageService拉取消息
Push模式下,消息拉取由PullMessageService服务实现,PullMessageService继承了ServiceThread,因此他也是一个异步线程任务。
我们来看看它的run方法,该方法在一个循环中,不断地从pullRequestQueue中阻塞式的获取并移除队列的头部数据,即拉取消息的请求,然后调用pullMessage方法根据该请求去broker拉取消息。
也就是说只要pullRequestQueue队列中有拉取请求,它就会去Broker拉取消息,如果没有就阻塞。
2 PullMessageService#pullMessage拉取消息
pullMessage方法是拉取消息的入口方法。内部实际调用DefaultMQPushConsumerImpl的pullMessage方法。
从consumerTable中获取pullRequest中保存的消费者组的消费者实例
3 DefaultMQPushConsumerImpl#pullMessage拉取消息
下面是DefaultMQPushConsumerImpl的pullMessage方法的源码,代码很长内容很多,但是我们只需要关心几个重点步骤和方法:
    1、服务状态校验。如果消费者服务状态异常,或者消费者暂停了,那么延迟发送拉取消息请求。
    2、流控校验。默认请款下,如果processQueue中已缓存的消息总数量大于设定的阈值,默认1000,或者processQueue中已缓存的消息总大小大于设定的阈值,默认100MB那么同样延迟发送拉取消息请求。
    3、顺序消费和并发消费的校验。如果是并发消费并且内存中消息的offset的最大跨度大于设定的阈值,默认2000。那么延迟发送拉取消息请求。如果是顺序消费并且没有锁定过,那么需要设置消费点位。
    4、创建拉取消息的回调函数对象PullCallback,当拉取消息的请求返回之后,将会调用回调函数。这里面的源码我们后面再讲。
    5、判断是否允许上报消费点位,如果是集群消费模式,并且本地内存有关于此mq的offset,那么设置commitOffsetEnable为true,表示拉取消息时可以上报消费位点给Broker进行持久化。
    6、调用pullAPIWrapper.pullKernelImpl方法真正的拉取消息。

    3.1 pullKernelImpl拉取消息
    PullAPIWrapper的方法,用于拉取消息。
    首先获取指定brokerName的broker地址,默认获取master地址,如果由建议的拉取地址,则获取建议的broker地址,没找到broker地址,那么更新topic路由信息再获取一次。
    找到了broker之后,校验版本号,通过之后构造PullMessageRequestHeader请求头,然后调用MQClientAPIImpl#pullMessage方法发送请求,进行消息拉取。

    3.2 pullMessage发起拉取消息请求
    MQClientAPIImpl的方法,首先构建构建请求命令对象,请求Code为PULL_MESSAGE,然后根据设置的消息拉取模式,调用不同的方法发起不同请求进行消息拉取。
    push消费模式默认异步拉取消息,即调用pullMessageAsync方法拉取消息。
    该方法内部调用remotingClient.invokeAsync方法,基于netty给broker发送异步消息,设置一个InvokeCallback回调对象。
    InvokeCallback#operationComplete方法将会在得到结果之后进行回调,内部调用pullCallback的回调方法。
    在回调方法中,如果解析到了响应结果,那么调用pullCallback#onSuccess方法处理,否则调用pullCallback#onException方法处理。

4 总结
本次我们讲解了DefaultMQPushConsumer消费者客户端如何发起的拉取消息请求。
消息拉取由PullMessageService服务实现,PullMessageService继承了ServiceThread,因此他也是一个异步线程任务,将会在线程任务中,不断循环的从pullRequestQueue中阻塞式的获取并移除队列的头部数据,即拉取消息的请求,然后调用pullMessage方法根据该请求去broker拉取消息。
发起拉取请求之前,会进行一系列校验,例如服务状态校验、流控校验、顺序消费和并发消费的校验,都通过之后,创建拉取消息的回调函数对象PullCallback,当拉取消息的请求返回之后,将会调用回调函数。最后通过pullAPIWrapper.pullKernelImpl方法真正的拉取消息。
最终,拉取消息请求Code为PULL_MESSAGE,push消费模式默认异步拉取消息,即调用pullMessageAsync方法拉取消息。服务端收到该请求之后,会处理该消息拉取请求,我们下文再讲。

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值