consumer
consumer要做的事,就是消费消息。
主要就是3件事
- consumer首先要知道自己要去哪个队列里面消费消息
- 而且还要保存消费进度offset,如果启动之后,才可以知道要去拿哪些数据。
- 负载均衡。同一个group里面的consumer,有一个RebalanceImpl去负责消费端的。如果消费者上线、下线,要通过它来协调。
对于保留消费进度offset,consumer中有个offsetStore。如果是广播模式,offset是保留在本地的,因为每一个consumer的进度可能不一样。对于集群模式,offset是保留在borker端,因为只要有一个consumer消费了,这个消息就不用再消费了。
有一个consumeMessageService,负责拉取数据,分为有序和无序。
有一个rebalanceService负责负载均衡。
启动的时候,会启动几个定时任务
- fetchNameServerAddr,获取nameServer信息,防止nameserver挂了。
- updateTopicRouteInfoFromNameServer。获取topic的路由信息。
- cleanOfflineBroker&&sendHeartbeatToAllBrokerWithLock
- persistAllConsumerOffset
根据方法名也知道是啥意思了。
来看一下具体的消费过程。
pullMessageService
// Start pull service
this.pullMessageService.start();
// Start rebalance service
this.rebalanceService.start();
pullMessageService有一个线程一直死循环执行。去pullRequestQueue获取PullRequest。
然后根据PullRequest去找到对应的consumer,执行consumer的pullMessage方法。
DefaultMQPushConsumerImpl的pullMessage方法里面会根据pullRequest的信息,去borker拉取数据。在回调函数里面,会去执行consumeMessageService.submitConsumeRequest()。将message提交到consumeMessageService。
之后会把msg封装成一个ConsumeRequest,提交到consumeExecutor线程池里面去执行。ConsumeRequest里面拿到listener,去执行我们自己写的consumeMessage
rebalanceService
start里面会调用this.rebalanceService.start(),这个里面会找到所有的consumer,对每个consumer进行负载均衡。
其中是对每个topic进行负载均衡,判断每个topic应该去哪些queue里面拉取消息。
然后调用RebalanceImpl#updateProcessQueueTableInRebalance,去更新processQueueTable,为每个messageQueue生成一个PullRequest。