• 首页 > 
  • 使用消息队列RocketMQ版实例时订阅关系不一致

使用消息队列RocketMQ版实例时订阅关系不一致

KB: 29641

 · 

更新时间:2021-03-12 10:25

问题描述

在使用消息队列RocketMQ版实例时,可能会出现订阅关系不一致的情况,具体的问题现象如下:

  • 消息队列RocketMQ版控制台中订阅关系是否一致显示为否。
  • 消费者(Consumer)实例未收到订阅的消息。

问题原因

确保订阅关系一致的要求是同一个Group ID下的所有Consumer实例订阅的Topic和Tag完全一致。在JVM中启动配置同一个Group ID的多个Consumer实例时,如果出现以下任意一种情况,均可能导致消费逻辑混乱,消息丢失,最终表现为订阅关系不一致:

  • 相同Group ID下的Consumer实例订阅了不同的Topic。
  • 相同Group ID下的Consumer实例订阅了相同的Topic,但订阅的Tag不一致。

如果您想了解具体的错误示例,请参见更多信息

解决方案

阿里云提醒您:

  • 如果您对实例或数据有修改、变更等风险操作,务必注意实例的容灾、容错能力,确保数据安全。
  • 如果您对实例(包括但不限于ECS、RDS)等进行配置与数据修改,建议提前创建快照或开启RDS日志备份等功能。
  • 如果您在阿里云平台授权或者提交过登录账号、密码等安全信息,建议您及时修改。

请参考以下步骤进行检查:

  1. 检查您Consumer实例中与订阅相关的配置代码,确保配置同一个Group ID的所有Consumer实例均订阅相同的Topic及Tag。详情请参见订阅关系一致性
  2. 重启客户端应用。
  3. 登录消息队列RocketMQ版控制台,在左侧导航栏中单击实例列表,选择您的目标实例,进入实例详情页面。
  4. 在左侧导航栏中单击Group管理,选择对应的协议后,单击消费者状态,确认订阅关系是否一致显示为
  5. 测试并确认消息能够被预期的Consumer实例所消费。

更多信息

问题原因中两种可能性对应的错误示例及示例代码如下:

  • 相同Group ID下的Consumer实例订阅了不同的Topic。
    • 错误示例
      JVM1和JVM2中的Consumer实例均配置了同一个Group ID,例如GID-MQ-FAQ。但JVM1和JVM2中Consumer实例订阅的Topic不同。错误示例的代码请参见更多信息。
    • 示例代码
      • JVM1中的示例代码
        Properties properties = new Properties();
        properties.put(PropertyKeyConst.GROUP_ID, "GID-MQ-FAQ");
        Consumer consumer = ONSFactory.createConsumer(properties);
        consumer.subscribe("MQ-FAQ-TOPIC-1", "NM-MQ-FAQ", new MessageListener() {
            public Action consume(Message message, ConsumeContext context) {
                System.out.println("Receive: " + message);
                return Action.CommitMessage;
            }
        });
        consumer.start();
        说明:JVM1中Consumer实例订阅的Topic是MQ-FAQ-TOPIC-1。
      • JVM2中的示例代码
        Properties properties = new Properties();
        properties.put(PropertyKeyConst.GROUP_ID, "GID-MQ-FAQ");
        Consumer consumer = ONSFactory.createConsumer(properties);
        consumer.subscribe("MQ-FAQ-TOPIC-2", "NM-MQ-FAQ", new MessageListener() {
            public Action consume(Message message, ConsumeContext context) {
                System.out.println("Receive: " + message);
                return Action.CommitMessage;
            }
        });
        consumer.start();
        说明:JVM2中Consumer实例订阅的Topic是MQ-FAQ-TOPIC-2。
  • 相同Group ID下的Consumer实例订阅了相同的Topic,但订阅的Tag不一致。
    • 错误示例
      JVM1和JVM2中的Consumer实例均配置了同一个Group ID,例如GID-MQ-FAQ,也订阅了相同的Topic,例如MQ-FAQ-TOPIC-1。但JVM1和JVM2中Consumer实例订阅的Tag不同。
    • 示例代码
      • JVM1中的示例代码
        Properties properties = new Properties();
        properties.put(PropertyKeyConst.GROUP_ID, "GID-MQ-FAQ");
        Consumer consumer = ONSFactory.createConsumer(properties);
        consumer.subscribe("MQ-FAQ-TOPIC-1", "NM-MQ-FAQ-1", new MessageListener() {
            public Action consume(Message message, ConsumeContext context) {
                System.out.println("Receive: " + message);
                return Action.CommitMessage;
            }
        });
        consumer.start();
        说明:JVM1中Consumer实例订阅的Tag是NM-MQ-FAQ-1。
      • JVM2中的示例代码
        Properties properties = new Properties();
        properties.put(PropertyKeyConst.GROUP_ID, "GID-MQ-FAQ");
        Consumer consumer = ONSFactory.createConsumer(properties);
        consumer.subscribe("MQ-FAQ-TOPIC-1", "NM-MQ-FAQ-2", new MessageListener() {
            public Action consume(Message message, ConsumeContext context) {
                System.out.println("Receive: " + message);
                return Action.CommitMessage;
            }
        });
        consumer.start();
        说明:JVM2中Consumer实例订阅的Tag是NM-MQ-FAQ-2。

适用于

  • 消息队列RocketMQ版

如果您的问题仍未解决,您可以在阿里云社区免费咨询,或提交工单联系阿里云技术支持。