RocketMQ一个实例能消费另一个就不能消费

从你现象上看,最可能的情况是:你的消费端A 和 B属于同一个消费组(ConsumerGroup)。但是两个实例(消费端)却订阅了不同的topic即不同的订阅关系(一个订阅T1,一个订阅T2)。这在RocketMQ中是明确声明过的——“同一个消费组应该拥有完全一样的订阅关系”。拥有不同的订阅关系就有可能会导致你的现象。具体底层的原因来自于RocketMQ对于负载均衡分配queue的策略。简单的说就是每次分配queue的时候,相互的计算互相被干扰了,导致了漏分queue的现象。更多负载均衡的解析请参看:RocketMQ中关于消费者Rebalance过程? - Jaskey Lam 的回答 - RocketMQ--水平扩展及负载均衡详解 - 薛定谔的风口猪
■网友
1.
【RocketMQ一个实例能消费另一个就不能消费】 假设有消费组 g1,有消费者 c1 和 c2,c1 订阅了 topicA,c2 订阅了 topicB,集群内有 broker1 和broker2,假设 topicA 有 8 个消息队列,broker_a(q0/q1/q2/q3) 和 broker_b(q0/q1/q2/q3),前面我们知道 findConsumerIdList 方法会获取消费组内所有消费者客户端 ID,topicA 经过平均分配算法进行分配之后的消费情况如下:
c1:broker_a(q0/q1/q2/q3)
c2:broker_b(q0/q1/q2/q3)
问题就出现在这里,c2 根本没有订阅 topicA,但根据分配算法,却要加上 c2 进行分配,这样就会导致这种情况有一半的消息被分配到 c2 进行消费,被分配到 c2 的消息队列会延迟十几秒甚至更久才会被消费,topicB 同理。
2.
假设有消费者组 g1,g1下有消费者 c1 和消费者 c2,c1 订阅了 topicA,c2 订阅了 topicB,此时c2 先启动,将 g1 的订阅信息更新为 topicB,c1 随后启动,将 g1 的订阅信息覆盖为 topicA,c1 的 Rebalance 负载将 topicA 的 pullRequest 添加到 pullRequestQueue 中,而恰好此时 c2 心跳包又将 g1 的订阅信息更新为 topicB,那么此时 c1 的 PullMessageService 线程拿到 pullRequestQueue 中 topicA 的 pullRequest 进行消息拉取,然而在 broker 端找不到消费者组 g1 下 topicA 的订阅信息(因为此时恰好被 c2 心跳包给覆盖了),就会报消费者订阅信息不存在的错误了。


■网友
消费模式有集群消费和广播消费,如果你要的效果是,消费者B和消费者C都消费生产者A的所有消息,使用广播消费。如果是集群消费,你使用推消息消费消息,生产者A发了a1,a2,你想让消费者B和消费者C都能同时消费,只需要修改订阅topic,如果只有单个消费者消费。那你尝试下使用不同的consumerGroup的名字。以上是我个人的一些见解,希望能帮到你


    推荐阅读