订阅一致性的可能情况以及处理方案

订阅关系一致指的是同一个消费者 Group ID 下所有 Consumer 实例的处理逻辑必须完全一致。一旦订阅关系不一致,消息消费的逻辑就会混乱,甚至导致消息丢失

保持订阅关系一致意味着同一个消费者 Group ID 下所有的实例需在以下两方面均保持一致
订阅的 Topic 必须一致
订阅的 Topic 中的 Tag 必须一致

错误情况:

  1. 同一个 Group ID 下的两个实例订阅的 Topic 不一致
  2. 同一个 Group ID 下订阅 Topic 的 Tag 不一致。Consumer 实例 1 订阅了 TagA,而 Consumer 实例 2 未指定 Tag
  3. 同一个 Group ID 下订阅 Topic 个数不一致/同一个 Group ID 下订阅 Topic 的 Tag 不一致

我的错误:同一个Group和同一个Topic, 由于tag不同。 所以采取了两个消费者实例去分别消费消息,然后控制台会出现

emq 订阅多个topic rocketmq多个group订阅一个topic_阿里云

/**
	* 错误处理方式
	*/
 	/**
     * tag消息订阅
     * @param merchantPersonalService
     * @return
     */
    @Bean(initMethod = "start",destroyMethod = "shutdown")
    public ConsumerBean getMerchantBindingBankCardConsumer(MerchantPersonalService merchantPersonalService){
        ConsumerBean consumerBean = new ConsumerBean();
        Properties properties = new Properties();
        properties.put(PropertyKeyConst.GROUP_ID, merchantBankCardGroupId);
        // AccessKey 阿里云身份验证,在阿里云服务器管理控制台创建
        properties.put(PropertyKeyConst.AccessKey, accessKey);
        // SecretKey 阿里云身份验证,在阿里云服务器管理控制台创建
        properties.put(PropertyKeyConst.SecretKey, secretKey);
        // 设置 TCP 接入域名,进入控制台的实例管理页面的“获取接入点信息”区域查看
        properties.put(PropertyKeyConst.NAMESRV_ADDR, namesrvAddr);
        consumerBean.setProperties(properties);
        //组装订阅者消息
        Map<Subscription, MessageListener> map = new HashMap<Subscription, MessageListener>();
        Subscription subscription = new Subscription();
        //绑定商户银行卡信息mq的topic和tag
        subscription.setTopic(merchantBankCardTopic);
        subscription.setExpression(merchantBankCardBindTag);
        map.put(subscription, new AddBindingBankCardConsumerListener());
        consumerBean.setSubscriptionTable(map);
        return consumerBean;
    }

    /**
     * tag2消息订阅
     * @param merchantPersonalService
     * @return
     */
    @Bean(initMethod = "start",destroyMethod = "shutdown")
    public ConsumerBean getMerchantBankUntyingConsumer(MerchantPersonalService merchantPersonalService){
        ConsumerBean consumerBean = new ConsumerBean();
        Properties properties = new Properties();
        properties.put(PropertyKeyConst.GROUP_ID, merchantBankCardGroupId);
        // AccessKey 阿里云身份验证,在阿里云服务器管理控制台创建
        properties.put(PropertyKeyConst.AccessKey, accessKey);
        // SecretKey 阿里云身份验证,在阿里云服务器管理控制台创建
        properties.put(PropertyKeyConst.SecretKey, secretKey);
        // 设置 TCP 接入域名,进入控制台的实例管理页面的“获取接入点信息”区域查看
        properties.put(PropertyKeyConst.NAMESRV_ADDR, namesrvAddr);
        consumerBean.setProperties(properties);
        //组装订阅者消息
        Map<Subscription, MessageListener> map = new HashMap<Subscription, MessageListener>();
        Subscription subscription = new Subscription();
        //解绑商户银行卡信息mq的topic和tag
        subscription.setTopic(merchantBankCardTopic);
        subscription.setExpression(merchantBankCardUntyingTag);
        map.put(subscription, new UntyingBankCardConsumerListener());
        consumerBean.setSubscriptionTable(map);
        return consumerBean;
    }
    /**
	* 正确处理方式
	*/
	/**
     * 同一个Group和同一个Topic, tag不同的消息订阅()
     * @param
     * @return
     */
    @Bean(initMethod = "start",destroyMethod = "shutdown")
    public ConsumerBean getMerchantBindingBankCardConsumer(){
        ConsumerBean consumerBean = new ConsumerBean();
        Properties properties = new Properties();
        properties.put(PropertyKeyConst.GROUP_ID, merchantBankCardGroupId);
        // AccessKey 阿里云身份验证,在阿里云服务器管理控制台创建
        properties.put(PropertyKeyConst.AccessKey, accessKey);
        // SecretKey 阿里云身份验证,在阿里云服务器管理控制台创建
        properties.put(PropertyKeyConst.SecretKey, secretKey);
        // 设置 TCP 接入域名,进入控制台的实例管理页面的“获取接入点信息”区域查看
        properties.put(PropertyKeyConst.NAMESRV_ADDR, namesrvAddr);
        consumerBean.setProperties(properties);
        //组装订阅者消息
        Map<Subscription, MessageListener> map = new HashMap<>();
        Subscription subscription = new Subscription();
        //绑定商户银行卡信息mq的topic和tag
        subscription.setTopic(merchantBankCardTopic);
        subscription.setExpression(merchantBankCardBindTag+ "||" + merchantBankCardUntyingTag);
        map.put(subscription, addBindingBankCardConsumerListener);
        consumerBean.setSubscriptionTable(map);
        return consumerBean;
    }