关于 RocketMQ中 GroupID 与 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

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

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

  • 7
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
订阅RocketMQ多个消费组的死信队列,您需要进行以下步骤: 1. 在Spring Boot应用程序添加RocketMQ依赖项,例如: ```xml <dependency> <groupId>org.apache.rocketmq</groupId> <artifactId>rocketmq-spring-boot-starter</artifactId> <version>2.1.1</version> </dependency> ``` 2. 在应用程序的配置文件添加RocketMQ相关的配置,例如: ```yaml rocketmq: name-server: localhost:9876 producer: group: my-group consumer: group: my-consumer-group dead-letter-queue: enabled: true topic: my-dlq-topic ``` 3. 在应用程序创建多个RocketMQ消费者,并将其分配给不同的消费组。例如: ```java @Service @RocketMQMessageListener(topic = "my-topic", consumerGroup = "my-group1") public class MyConsumer1 implements RocketMQListener<String> { @Override public void onMessage(String message) { // TODO: 处理消息 } } @Service @RocketMQMessageListener(topic = "my-topic", consumerGroup = "my-group2") public class MyConsumer2 implements RocketMQListener<String> { @Override public void onMessage(String message) { // TODO: 处理消息 } } ``` 4. 创建一个死信队列消费者,并将其分配给一个消费组。例如: ```java @Service @RocketMQMessageListener(topic = "my-dlq-topic", consumerGroup = "my-dlq-consumer-group") public class MyDLQConsumer implements RocketMQListener<String> { @Override public void onMessage(String message) { // TODO: 处理死信消息 } } ``` 通过以上步骤,您就可以订阅RocketMQ多个消费组的死信队列了。在配置文件,您需要将死信队列功能启用,并设置死信队列的主题。然后在消费者,您需要将它们分配给不同的消费组。最后,您需要创建一个特定的消费者来处理死信队列消息

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值