问题现象

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. linux小倒腾

    1.vim安装,sudo apt-get install vim-gtk,于是vim就安装好了.当然在我电脑上还出现了gvim,简单的vim配置(etc/vim/vimrc): "我的设置 ...

  2. 06 str() bytes() 编码转换

    x = str() #创建字符串#转换成字符串,字节,编码 m = bytes()#创建字节#转换成字节,字符串,要编程什么编码类型的字节 a = "李露" b1 = bytes( ...

  3. CSS背景与边框属性-----box-shadow

    box-shadow:none | <shadow> [ , <shadow> ]*   <shadow> = inset? && <leng ...

  4. linux常用命令:cd 命令

    Linux cd 命令可以说是Linux中最基本的命令语句,其他的命令语句要进行操作,都是建立在使用 cd 命令上的.所以,学习Linux 常用命令,首先就要学好 cd 命令的使用方法技巧. 1. 命 ...

  5. 转:C#串口编程

    本文用来简单介绍一下C#串口编程的知识,主要以实例为内容. 凡是串口设备和计算机交互的时候都用到串口,在C#中我们如何来操作串口呢? 大话串口工作原理 实际串口是用来和外部设备进行交换数据的,我抽象出 ...

  6. 普通程序员转型AI免费教程整合,零基础也可自学

    普通程序员转型AI免费教程整合,零基础也可自学 本文告诉通过什么样的顺序进行学习以及在哪儿可以找到他们.可以通过自学的方式掌握机器学习科学家的基础技能,并在论文.工作甚至日常生活中快速应用. 可以先看 ...

  7. 直播协议的选择:RTMP vs. HLS

    文章转自:直播协议的选择:RTMP vs. HLS 前言 随着直播业务的兴起,越来越多的直播平台开始涌现,这火热的程度好像一个应用不带上直播业务出来都不好意思跟人打招呼.想要做一个直播业务,主要包括三 ...

  8. Django后端项目---- rest framework(3)

    一.版本 程序也来越大时,可能通过版本不同做不同的处理 没用rest_framework之前,我们可以通过以下这样的方式去获取. class UserView(APIView): def get(se ...

  9. 不懂RPC实现原理怎能实现架构梦

    RPC(Remote Procedure Call Protocol)——远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议.RPC协议假定某些传输协议的存在 ...

  10. Ubuntu16.04+cuda8.0rc+opencv3.1.0+caffe+Theano+torch7搭建教程

    https://blog.csdn.net/jywowaa/article/details/52263711 学习中用到深度学习的框架,需要搭建caffe.theano和torch框架.经过一个月的不 ...