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

問題現象

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

producer.setDefaultTopicQueueNums(8);

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

defaultTopicQueueNums=16

 

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


查找原因,服務端與客戶端配置對比

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


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

定位問題在服務端TopicConfig

打印這兩個變量:

客戶隊列數clientDefaultTopicQueueNums8,正確;

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_TOPICConfig對象屬性值的真實來源,繼續閱讀源碼,發現borker有兩處改寫DEFAULT_TOPICConfig對象的位置:


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


    一處是在BrokerControllerinitialize方法裏調用了TopicConfigManager.load方法:

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

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

 

最終結論

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

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

 

阿里的解釋

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

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

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

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

 

解決辦法


  • 通過producer.createTopic方法創建(實現的方式是將創建命發送到控制檯),可以創建成功,但會報應答超時失敗,原因未查;

  • 通過控制檯方式創建;

  • 修改metaq源碼重新編譯borker,使用broker的配置信息覆蓋defaultTopic的配置信息。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章