消息隊列(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;
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章