RocketMQ消费者端消息列队六种负载均衡算法分析

在RocketMQ启动的时候会启动负载均衡线程,过程如下:
//DefaultMQPullConsumerImpl.start()
 mQClientFactory.start();
 //上面点进去 ->MQClientInstance.start(),rebalanceService继承了ServiceThread,
 //ServiceThread实现了Runnable接口
 this.rebalanceService.start();
 //继续下一层,MQClientInstance.doRebalance()找到下面
 impl.doRebalance();
 //..在一层层点进去,最后找到RebalanceImpl.rebalanceByTopic方法,找到
 AllocateMessageQueueStrategy strategy = this.allocateMessageQueueStrategy;

AllocateMessageQueueStrategy就是实现消费者消息队列负载均衡算法的接口。
该接口在rocketMq-4.3.0版本中有六种实现方法:

  • AllocateMessageQueueAveragely:平均算法
  • AllocateMessageQueueAveragelyByCircle:环形平均算法
  • AllocateMessageQueueByConfig:根据配置负载均衡算法
  • AllocateMessageQueueByMachineRoom:根据机房负载均衡算法
  • AllocateMessageQueueConsistentHash:一致性哈希负载均衡算法
  • AllocateMachineRoomNearby:靠近机房策略

在客户端没有指定的情况下,RocketMQ默认使用AllocateMessageQueueAveragely平均算法。

一、 AllocateMessageQueueAveragely平均负载均衡算法

平均算法顾名思义就是取平均值,该方法四个参数,consumerGroup(消费者组名称)、
currentCID(当前消费者的id)、mqAll(当前topic下面所有的消息队列)、cidAll(当前消费者组下面所有的消费者id)。算法思想就是把算出平均值然后将连续的队列分配给每个消费者。假设队列大小是8(编号0-7),消费者数量3(编号0-2),分配结果就是:
消费者0:队列0,1,2;
消费者1:队列3,4,5;
消费者2:队列6,7。
下面具体来看代码:


 @Override
    public List<MessageQueue> allocate(String consumerGroup, String currentCID, List<MessageQueue> mqAll,
        List<String> cidAll) {
   
        if (currentCID == null || currentCID.length() < 1) {
   
            throw new IllegalArgumentException("currentCID is empty");
        }
        if (mqAll == null || mqAll.isEmpty()) {
   
            throw new IllegalArgumentException("mqAll is null or mqAll empty");
        }
        if (cidAll == null || cidAll.isEmpty()) {
   
            throw new IllegalArgumentException("cidAll is null or cidAll empty");
        }

        List<MessageQueue> result = new ArrayList<MessageQueue>();
        if (!cidAll.contains(currentCID)) {
   
            log.info("[BUG] ConsumerGroup: {} The consumerId: {} not in cidAll: {}",
                consumerGroup,
                currentCID,
                cidAll);
            return result;
        }
//        cidAll.size() = 3; mqAll.size()=8;mod=2;
//      index=0;averageSize=3;startIndex=0;range=3,result={0,1,2}
//      index = 1;averageSize=3;startIndex=3;range = 3;result={3,4,5}
//      index = 2;averageSize=2;startIndex=6;range = 2;result={6,7}
        int index = cidAll.indexOf(currentCID);
        //取模a除以b的余数
        int mod = mqAll.size() % cidAll.size();
        int averageSize =
            mqAll.size() <= cidAll.size() ? 1 : (mod > 0 && index < mod ? mqAll.size() / cidAll.size()
                + 1 : mqAll.size() / cidAll.size());
        int startIndex = (mod > <
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值