消费端负载均衡
消费端会通过RebalanceService线程,10秒钟做一次基于topic下的所有队列负载
消费端遍历自己的所有topic,依次调rebalanceByTopic
根据topic获取此topic下的所有queue
选择一台broker获取基于group的所有消费端(有心跳向所有broker注册客户端信息)
选择队列分配策略实例AllocateMessageQueueStrategy执行分配算法,获取队列集合Set
1) 平均分配算法,其实是类似于分页的算法
将所有queue排好序类似于记录
将所有消费端consumer排好序,相当于页数
然后获取当前consumer所在页面应该分配到的queue
2) 按照配置来分配队列, 也就是说在consumer启动的时候指定了queue
3) 按照机房来配置队列
Consumer启动的时候会指定在哪些机房的消息
获取指定机房的queue
然后在执行如1)平均算法
根据分配队列的结果更新ProccessQueueTable
1) 比对mqSet 将多余的队列删除,当broker当机或者添加,会导致分配到mqSet变化,
a) 将不在被本consumer消费的messagequeue的ProcessQueue删除,其实是设置ProcessQueue的droped属性为true
b) 将超过两份中没有拉取动作ProcessQueue删除
//TODO 为什么要删除掉,两分钟后来了消息怎么办?
//
2) 添加新增队列,比对mqSet,给新增的messagequeue
构建长轮询对象PullRequest对象,会从broker获取消费的进度
构建这个队列的ProcessQueue
将PullRequest对象派发到长轮询拉消息服务(单线程异步拉取)
注:ProcessQueue正在被消费的队列,
(1) 长轮询拉取到消息都会先存储到ProcessQueue的TreeMap
TreeMap
(2) 对于顺序消息消费处理
locked属性:当consumer端向broker申请锁队列成功后设置true,只有被锁定的processqueue才能被执行消费
rollback: 将消费在msgTreeMapTemp中的消息,放回msgTreeMap重新消费
commit: 将临时表msgTreeMapTemp数据清空,代表消费完成,放回最大偏移值
(3) 这里是个TreeMap,对key即消息的offset进行排序,这个样可以使得消息进行顺序消费