大家好,欢迎来到IT知识分享网。
问题
在阿里云服务提供的消息队列服务(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 的消费者实例被分配到了消息队列,就会导致消费队列中的消息消费失败。
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/16262.html