RocketMQ 消费者(二) - 负载均衡 (图解)
RocketMQ 消费者(二) - 负载均衡 (图解)
1. 负载均衡入口
如图, 负载均衡服务 实际上是运行在 客户端实例中, 是一个周期性执行的服务,正常情况下 每20s执行一次。
负载均衡方法 最终会 来到 每个消费者内部的 负载均衡实例对象中, 然后根据消费者本地的 订阅集合, 来进行负载均衡。
最终的方法执行入口则来到RebalanceImpl#rebalanceByTopic()
方法中 。
2. 集群模式的负载均衡
以上 是 经过负载均衡分配算法 的流程图, 最终会拿到 属于 该消费者端 所订阅的 topic 的 队列集合。
- 获取 当前主题的 所有队列分布信息
Set<MessageQueue> mqSet = this.topicSubscribeInfoTable.get(topic);
- 获取 消费者组客户端 id 集合 (从broker服务器获取)
List<String> cidAll = this.mQClientFactory.findConsumerIdList(topic, consumerGroup);
- 执行负载均衡分配算法
allocateResult = strategy.allocate(this.consumerGroup,
this.mQClientFactory.getClientId(),mqAll, cidAll);
- 根据最终的 分配结果 去更新 processQueueTable 的数据。
boolean changed = this.updateProcessQueueTableInRebalance(topic, allocateResultSet, isOrder);
该方法 会遍历processQueueTable 中的 MessageQueue 是否在 新分配的集合中 , 会做如下几件事:
- 将 processQueueTable 中 不在新分配集合中的 mq删除, 同时删除 offsetStore 中的该mq
- 将 processQueueTable 中 超时未拉取新消息的 mq 删除,同时删除 offsetStore 中的该mq
- 添加 新分配的 mq 到 processQueueTable 中 。 并向 拉消息服务 中发起 已给 拉取 该mq消费信息的 请求。
3.负载均衡策略图解
4. 两种消费模式下的负载均衡
1.并发消费下的负载均衡
2.顺序消费下的负载均衡
我们可以看到 顺序消费下的负载均衡 与 并发消费下的负载均衡 基本上都是一致的,只不过在将MessageQueue添加到 ProcessQueueTable 的过程中,会先去Broker端获取一把分布式锁, 这就代表 该MessageQueue 只能改消费者组下的该消费者 来消费, 因此也就在 所有消费者的层面上 锁定了 该MessageQueue。
万般皆下品,唯有读书高!