Rocketmq之正確設置InstanceName


  引用 (2條消息) rocketmq問題匯總-instanceName參數何時該設置?_MQCloud的專欄-CSDN博客

  1 producer

  默認情況下不需要設置instanceName,rocketmq會使用ip@pid(pid代表jvm名字)作為唯一標示
  

  如果同一個jvm中,不同的producer需要往不同的rocketmq集群發送消息,需要設置不同的instanceName
原因如下:如果不設置instanceName,那么會使用ip@pid作為producer唯一標識,那么會導致多個producer內部只有一個MQClientInstance(與mq交互)實例,從而導致只往一個集群發消息。

  2 consumer

  默認情況下不需要設置instanceName,rocketmq會使用ip@pid作為instanceName(pid代表jvm名字)
如果設置instanceName,rocketmq會使用ip@instanceName作為consumer的唯一標示,此時需要注意instanceName需要不同。
  

  如果consumer設置了instanceName,如果是多台主機上,每一台主機一個JVM進程,這種情況還好。如果是一台主機上,多個JVM進程,且每個consumer的instanceName還相同的情況下,就會出現只有一台consumer消費全部消息的情況。

  因為 rocketmq會使用ip@instanceName作為consumer的唯一標示,這樣多個JVM進程中的consumer只有一種cid

  這樣在rebalance過程中,會導致只有一個consumer消費所有messagequeue

  AllocateMessageQueueAveragely # allocate

public List<MessageQueue> allocate(String consumerGroup, String currentCID, List<MessageQueue> mqAll,
        List<String> cidAll) {
        if (currentCID == null || currentCID.length() < 1) {
            throw new IllegalArgumentException("currentCID is empty");
        }
        if (mqAll == null || mqAll.isEmpty()) {
            throw new IllegalArgumentException("mqAll is null or mqAll empty");
        }
        if (cidAll == null || cidAll.isEmpty()) {
            throw new IllegalArgumentException("cidAll is null or cidAll empty");
        }

        List<MessageQueue> result = new ArrayList<MessageQueue>();
        if (!cidAll.contains(currentCID)) {
            log.info("[BUG] ConsumerGroup: {} The consumerId: {} not in cidAll: {}",
                consumerGroup,
                currentCID,
                cidAll);
            return result;
        }

        int index = cidAll.indexOf(currentCID);
        int mod = mqAll.size() % cidAll.size();//cidAll實際只有一個成員 mod 就是0 int averageSize =
            mqAll.size() <= cidAll.size() ? 1 : (mod > 0 && index < mod ? mqAll.size() / cidAll.size()
                + 1 : mqAll.size() / cidAll.size());
        int startIndex = (mod > 0 && index < mod) ? index * averageSize : index * averageSize + mod;//startIndex就是0 int range = Math.min(averageSize, mqAll.size() - startIndex);
        for (int i = 0; i < range; i++) {
            result.add(mqAll.get((startIndex + i) % mqAll.size()));
        }
        return result;
    }

  這樣就是永遠一個consumer消費了所有messageQueue。

  不過這種情況也比較極端,一台主機跑一個系統下的多個JVM這不多見


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM