消息队列(RocketMQ):订阅消息一致性问题解决方案

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

订阅关系一致指的是同一个消费者 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不同。 所以采取了两个消费者实例去分别消费消息,然后控制台会出现在这里插入图片描述

	/**
	* 错误处理方式
	*/
 	/**
     * 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;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值