为什么在一段时间内RocketMQ的队列同时分配给了两个消费者?详细剖析消费者负载均衡中的坑...

本文深入剖析RocketMQ消费者负载均衡机制,解释Rebalance过程如何决定队列分配,探讨其在多Topic分配及触发时机,并分析可能导致消息重复的因素。RocketMQ采用无中心的Rebalance策略,确保消费者实例有序地分配队列,但这种机制可能导致消息重复问题,需要消费者端实现消费幂等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

消费者大概是怎么做负载均衡的(集群模式),如下图所示:


集群模式下,每个消费者实例会被分配到若干条队列。正因为消费者拿到了明确的队列,所以它们才能针对对应的队列做循环拉取消息的处理,以下是消费者客户端和broker通信的部分代码,可以看到通信的参数里有一个重要的参数,就是 queueId
PullMessageRequestHeader requestHeader = new PullMessageRequestHeader();
        requestHeader.setConsumerGroup(this.consumerGroup);
        requestHeader.setTopic(mq.getTopic());
        requestHeader.setQueueId(mq.getQueueId());//消息拉取必须显示的告诉broker拉取哪个queue的消息
        requestHeader.setQueueOffset(offset);
        requestHeader.setMaxMsgNums(maxNums);
        requestHeader.setSysFlag(sysFlagInner);
        requestHeader.setCommitOffset(commitOffset);
        requestHeader.setSuspendTimeoutMillis(brokerSuspendMaxTimeMillis);
        requestHeader.setSubscription(subExpression);
        requestHeader.setSubVersion(subVersion);
        requestHeader.setExpressionType(expressionType);

        String brokerAddr = findBrokerResult.getBrokerAddr();
        if (PullSysFlag.hasClassFilterFlag(sysFlagInner)) {
            brokerAddr = computPullFromWhichFilterServer(mq.getTopic(), brokerAddr);
        }

        PullResult pullResult = this.mQClientFactory.getMQClientAPIImpl().pullMessage(
            brokerAddr,
            requestHeader,
            timeoutMillis,
            communicationMode,
            pullCallback);
  • 这侧面也再次印证,RocketMQ的消费模型是Pull模式。
  • 同时,对于每个消费者实例来说,在每个消息拉取之前,实际上都是确定了队列的(不会轻易发生改变),如下图控制台所示:

本文尝试对RocketMQ负载均衡(哪个消费者消费哪些队列)的原理进行解析,希望能让大家对其中的基本原理进行了解,并对部分问题能作出合理解析和正确规避。

————————————————————————————————————————————————

所谓Rebalance到底在解决什么问题

  • RocketMQ每

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值