问题现象

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的配置信息。

最新文章

  1. Android获取位置信息的方法总结
  2. Ubuntu 安装 JDK 7
  3. php截取utf-8中文字符串乱码的解决方法
  4. 矩阵乘法 --- hdu 4920 : Matrix multiplication
  5. js快速排序方法
  6. 【JAVA正则表达式综合练习】
  7. Oracle中增加,修改,删除表中的列
  8. UITableView添加静态背景.
  9. Populating Next Right Pointers in Each Node 解答
  10. Spyder提示ValueError: API &#39;QString&#39; has already been set to version 1
  11. framework7+node+mongo项目
  12. 【python密码学编程】7.暴力破解凯撒加密法
  13. 201521123084 《Java程序设计》第2周学习总结
  14. 代码的完整性:打印1到最大的n位数
  15. Android程序崩溃异常收集框架
  16. 关于Python的Mixin模式
  17. Java高级特性 第2节 java中常用的实用类(1)
  18. getResourceAsStream的3种路径配置
  19. Android源码50例汇总,欢迎各位下载(转载)
  20. sublime3 安装 Package Control 报错 “There Are No Packages Available For Installation”

热门文章

  1. Semaphore wait has lasted &gt; 600 seconds
  2. [ Learning ] Design Pattens
  3. Java IO/NIO教程
  4. AssetBoundle加载非预设资源
  5. hdu5441 并查集+克鲁斯卡尔算法
  6. C++前置声明
  7. svnrdump:E175000:SSL is not supported错误的解决
  8. Linux基础命令---iptables-save
  9. Linux基础命令---apwatch
  10. window、linux安装jdk,excel 导入oracle,WebService,window 端口查看,svn服务安装,oracle用户解锁