RocketMQ3.2.2生產者發送消息自動創建Topic隊列數無法超過4個


問題現象

RocketMQ3.2.2版本,測試時嘗試發送消息時自動創建Topic,設置了隊列數量為8:

producer.setDefaultTopicQueueNums(8);

同時設置broker服務器的配置文件broker.properties:

defaultTopicQueueNums=16

 

但實際創建后從控制台及后台打印代碼觀察到該Topic只創建了4個隊列,反復重試確認發送消息時自動創建Topic,最大創建4個隊列。

 

查找原因

服務端與客戶端配置對比

  閱讀源碼,在TopicConfigManager的createTopicInSendMessageMethod方法,有對比TopicConfig對象中的隊列數和客戶端設定隊列數,並選擇其中較小者為新建Topic隊列數的邏輯:

int queueNums = clientDefaultTopicQueueNums > defaultTopicConfig.getWriteQueueNums() ? defaultTopicConfig.getWriteQueueNums() : clientDefaultTopicQueueNums;

定位問題在服務端TopicConfig

打印這兩個變量:

客戶隊列數clientDefaultTopicQueueNums為8,正確;

而defaultTopicConfig.getWriteQueueNums()為4,而非broker.properties中設定的16;

 

由可以確定是問題出在defaultTopicConfig上。

 

defaultTopicConfig數據來源

defaultTopicConfig是從ConcurrentHashMap<String, TopicConfig> topicConfigTable中取得,如下:

TopicConfig defaultTopicConfig = this.topicConfigTable.get(defaultTopic);

 

而defaultTopic默認值為MixAll.DEFAULT_TOPIC=“TBW102”。

 

  為了確認topicConfigTable中的為MixAll.DEFAULT_TOPIC的Config對象屬性值的真實來源,繼續閱讀源碼,發現borker有兩處改寫DEFAULT_TOPIC的Config對象的位置:

  一處是TopicConfigManager的構造方法,在borker服務器啟動時運行,會讀取broker.properties里的配置,此時DEFAULT_TOPIC的Config對象里的DefaultQueueNums為正確的我所配置的16;

  一處是在BrokerController的initialize方法里調用了TopicConfigManager.load方法:

  該load方法繼承自ConfigManager類,讀取了$ROCKETMQ_HOME\store\config下保存的配置信息,並調用抽象方法decode(),配置信息作為json字符串參數傳入到decode();

  TopicConfigManager類的decode實現方法里,讀取了$ROCKETMQ_HOME\store\config\topics.json里的配置信息,並覆寫到topicConfigTable,而此前生成的topics.json的“TBW102”的配置信息里的writeQueueNums及readQueueNums均為4。

 

最終結論

  在發送消息自動創建Topic時,對於此前已運行的borker服務器,修改配置文件的defaultTopicQueueNums屬性的值不起作用。

  因為發送消息自動創建Topic的實現里,隊列數取小對比操作的變量——defaultTopicConfig寫在topics.json的配置信息里的writeQueueNums及readQueueNums,讀取自Topics.json,所以即使修改配置文件並重啟borker服務器后也不會改變。而服務端最終會用topics.json的值覆蓋發送消息自動創建Topic時的TopicConfig配置信息。

 

阿里的解釋

隊列是資源,所以管控權會放到服務器。

但是每個用戶的默認策略又不一樣,所以會有一個默認topic作為模板,在未創建默認topic前,系統會自動創建一個。

這個可以占到運維的角度思考,例如你運維了10個集群,為1000個用戶服務。有些用戶需要動態的創建topic,但是不能給他足夠的權限,想創建多少創建多少。

所有會給他一個模板的topic,就是defaultTopic,動態創建topic繼承於defaultTopic配置,隊列數不能超過defaultTopic。

 

解決辦法

  1. 通過producer.createTopic方法創建;
  2. 通過控制台方式創建;
  3. 修改metaq源碼重新編譯borker,使用broker的配置信息覆蓋defaultTopic的配置信息。


免責聲明!

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



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