PullMessageService在启动时没有由于Linked pullRequestQueue中PullRequest对象,故PullMessageService线程将阻塞。
问题一:PullRequest对象什么时候加入pullRequestQueue中??
问题二:集群内多个消费者是如何负载主题下多个消息队列,并且新的消费者加入时,消息队列如何重新分布??
Rocketmq的消息队列负载主要是RebalanceService来实现;
MQClientInstance#doRebalance
DefaultMQPushConsumerImpl#doRebalance
RebalanceImpl#doRebalance
RebalanceImpl#rebalanceByTopic
(1)、从主题订阅的缓存消息中获取主题的队列信息;
Set<MessageQueue> mqSet = this.topicSubscribeInfoTable.get(topic);
List<String> cidAll = this.mQClientFactory.findConsumerIdList(topic, consumerGroup);
(2)、首先对cidAll,mqAll排序,确保同一个消费队列不会被多个消费者分配。RocketMq消息队列分配算法;
1)、AllocateMessageQueueAveragely 平均分配算法
如果现在有5个消息队列q1,q2,q3,q4,q5,有3个消费者,c1,c2,c3,消息队列分配如下:
c1:q1,q2
c2:q3,q4
c3:q5
2)、AllocateMessageQueueAveragelyByCircle 平均分配轮询
如果现在有5个消息队列q1,q2,q3,q4,q5,有3个消费者,c1,c2,c3,消息队列分配如下:
c1:q1,q4
c2:q2,q5
c3:q3
3)、AllocateMessageQueueConsistentHash 一致性hash
参考文章:https://blog.csdn.net/qq_40551994/article/details/100991581
4)、AllocateMessageQueueByConfig,根据配置,为每一个消费者定制消息队列
5)、AllocateMessageQueueByMachineRoom 根据broker部署的机房名,对每个消费者负责不同的broker队列
消费队列的分配遵循一个消费者可以分配多个消息队列,同一个消息队列只分配给一个消费者。
RocketMq消息拉取消息有PullMessage与Rebalance共同协作完成的;
参考文章:RocketMq架构设计与实现原理