问题现象

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

RocketMQ3.2.2生产者发送消息自动创建Topic队列数无法超过4个的更多相关文章

  1. 深入研究RocketMQ生产者发送消息的底层原理

    前言 hello,小伙伴们,王子又来和大家研究RocketMQ的原理了,之前的文章RocketMQ生产部署架构如何设计中,我们已经简单的聊过了生产者是如何发送消息给Broker的. 我们简单回顾一下这 ...

  2. 🏆【Alibaba中间件技术系列】「RocketMQ技术专题」Broker服务端自动创建topic的原理分析和问题要点指南

    前提背景 使用RocketMQ进行发消息时,一般我们是必须要指定topic,此外topic必须要提前建立,但是topic的创建(自动或者手动方式)的设置有一个开关autoCreateTopicEnab ...

  3. kafka 生产者发送消息

    KafkaProducer 创建一个 KafkaThread 来运行 Sender.run 方法. 1. 发送消息的入口在 KafkaProducer#doSend 中,但其实是把消息加入到 batc ...

  4. Kafka生产者发送消息的三种方式

    Kafka是一种分布式的基于发布/订阅的消息系统,它的高吞吐量.灵活的offset是其它消息系统所没有的. Kafka发送消息主要有三种方式: 1.发送并忘记 2.同步发送 3.异步发送+回调函数 下 ...

  5. kafka-0.10.2.1:Producer生产时无法自动创建Topic

    集群环境: CenterOS 1台 Kafka:0.10.2.1版本. 今天在测试环境下,我们的Kafka集群工作不正常,具体现象为,使用confulentkafka向kafka集群生产消息失败,且并 ...

  6. Kafka学习笔记(6)----Kafka使用Producer发送消息

    1. Kafka的Producer 不论将kafka作为什么样的用途,都少不了的向Broker发送数据或接受数据,Producer就是用于向Kafka发送数据.如下: 2. 添加依赖 pom.xml文 ...

  7. 大数据_Kafka_Kafka自动创建不存在的Topics / 删除已存在的Topics

    大数据_Kafka_Kafka自动创建不存在的Topics / 删除已存在的Topics 2016年10月11日 18:22:59 高达一号 阅读数:8655   版权声明:本文为博主原创文章,未经博 ...

  8. MSMQ-发送消息到远程专用队列 实例

    目录 一:MSMQ的一些理论上的知识 二:队列类型(Queue Type) 三:安装消息队列 四:在C#中Messagequeue class 五:MSMQ-发送消息到远程专用队列 六:例子   一. ...

  9. MSMQ-发送消息到远程专用队列path格式

    在工作组模式下,远程访问专用队列.在网上找到一篇文章,翻译了一下. 最后结论,直接使用多元素格式名方式,利用IP地址直接对单个或多个目标发送消息      MessageQueue rmQ = new ...

随机推荐

  1. C# 调用.bat 提示该命令不是内部命令或外部命令

    前提:双击.bat文件可以执行成功,用C#调用提示该命令不是内部命令或外部命令...... 解决方法:下面代码的红色标注,既要设置.bat文件的文件名FileName,也要设置.bat文件所在的文件夹 ...

  2. Marlin 擠出頭溫度控制PID值校正

    Marlin 擠出頭溫度控制PID值校正 擠出頭加熱器.溫度感應器安裝好後,先別急著直接指定工作溫度並且加熱.因為控制板上的溫度控制PID參數尚未校正.如果加熱速度過快,有可能會加熱過度並且導致零件燒 ...

  3. html5-颜色的表示

    div{width: 100%;height: 100px;}body{background: url(../pic/2.png);}/*#div1{background: #ff0000;}#div ...

  4. Sitecore CMS中更改项目的模板

    如何在Sitecore CMS中创建项目后更改项目的模板. 在创建项目时选择了错误的模板,或者创建了新模板并将现有项目更新为新模板时,这非常有用.   警告! 更改模板时要小心.如果原始模板具有不在新 ...

  5. Block 实践

    OC版 函数中无参无返回值 /* 作为函数参数类型的格式 返回值类型 (^)(形参列表) */ CZPerson.h - (void) test:(void (^)(void))block; CZPe ...

  6. Linux基础命令---tail显示文本

    tail 显示文本文件尾部的部分内容,默认显示最后10行. 此命令的适用范围:RedHat.RHEL.Ubuntu.CentOS.SUSE.openSUSE.Fedora. 1.语法         ...

  7. system call filters failed to install; check the logs and fix your configuration or disable system call filters at your own risk

    elasticsearch启动时遇到的错误 这个是elasticsearch配置文件的问题. 解决办法: 在elasticsearch.yml配置文件中 添加     bootstrap.system ...

  8. mongodb 批量修改

    db.getCollection(').find({}).forEach( function(item) { item.date = item.date.replace("2018-11-2 ...

  9. 51Nod 1072 威佐夫游戏

    题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1072 有2堆石子.A B两个人轮流拿,A先拿.每次可以从一堆 ...

  10. shell 获取随机字符串

    一直使用 /dev/urandom 和md5sum的方式去随机字符串,感觉还是不够随机,毕竟只有小写字母和数字嘛. 换换口味: [root@localhost ~]# arr=(`echo {a..z ...