ONS中GID与Topic订阅关系一致的疑惑

目录

基本概念

问题

解答

总结


基本概念

问题

在阿里云服务提供的消息队列服务(RocketMQ)中,给出了一份关于订阅关系一致的最佳实践,在文档中指出同一个 GroupID 中的所有消费者实例最好订阅同样的 Topic+Tag。这让我有一些疑问,为什么一个 GroupID 只能产生一种订阅,这样岂不是同一个应用需要订阅不同的 Topic 那么每一次都需要去申请一个 GroupID,这使得 GroupID 和 Topic 产生了一定的耦合关系,看起来是不太合理的,那么为什么 RocketMQ 要这么做呢?

解答

经过对源码的阅读找到了一部分关于这个问题的答案。

如果同一个 GroupID 下的不同消费者实例,订阅了不同的 Topic+Tag 将导致在对Topic 的消费队列进行负载均衡的时候产生不正确的结果,最终导致消息丢失。

在消费者客户端有一个名为 Rebalance 的类,会周期性的对消费者和订阅的 Topic 的消费队列(类似于 Kafka 的 Partition)进行负载均衡。在进行负载均衡的过程中,需要通过 mqClientFactory.findConsumerIdList(topic,consumerGroup) 方法去获取在这个 GroupId下所有订阅这个 topic 的 clientId。

看到这个地方就有一些疑问了,命名这里有根据 GroupID 和 Topic 作为参数去获取 ClientID 怎么会产生问题呢?继续往下看。


我们可以看到 findConsumerIdList 方法中并没有把 Topic 继续往下传递,而仅仅是用topic 作为一个获得 Broker 地址的参数,在实际之后获取 ClientId 的方法中并没有传入 Topic。这样就会导致这个调用会返回当前 GroupID 下所有的消费者实例,无论这个消费者是否订阅了当前这个 Topic。返回的 ClientID 会参与当前 Topic 的消费对类的负载均衡,如果没有订阅这个 Topic 的消费者实例被分配到了消息队列,就会导致消费队列中的消息消费失败。

总结

所以,新接topic时,需要新申请GID。否则本地开发环境 可能消费失败。

猜你喜欢

转载自blog.csdn.net/lan861698789/article/details/112165708