作者 | 丁威

责编 | 胡巍巍

现象

很多网友会问,为什么明明集群中有多台Broker服务器,autoCreateTopicEnable设置为true,表示开启Topic自动创建,但新创建的Topic的路由信息只包含在其中一台Broker服务器上,这是为什么呢?

期望值:为了消息发送的高可用,希望新创建的Topic在集群中的每台Broker上创建对应的队列,避免Broker的单节点故障。

现象截图如下:

Broker集群信息

topicTest5路由信息

正如上图所示,自动创建的topicTest5的路由信息:

  • topicTest5只在broker-a服务器上创建了队列,并没有在broker-b服务器创建队列,不符合期望。

  • 默认读写队列的个数为4。

我们再来看一下RocketMQ默认topic的路由信息截图如下:

从图中可以默认Topic的路由信息为broker-a、broker-b上各8个队列。

思考

默认Topic的路由信息是如何创建的?

  1. Topic的路由信息是存储在哪里?Nameserver?broker?

  2. RocketMQ Topic默认队列个数是多少呢?

原理

3.1 RocketMQ基本路由规则

  1. Broker在启动时向Nameserver注册存储在该服务器上的路由信息,并每隔30s向Nameserver发送心跳包,并更新路由信息。

  2. Nameserver每隔10s扫描路由表,如果检测到Broker服务宕机,则移除对应的路由信息。

  3. 消息生产者每隔30s会从Nameserver重新拉取Topic的路由信息并更新本地路由表;在消息发送之前,如果本地路由表中不存在对应主题的路由消息时,会主动向Nameserver拉取该主题的消息。

回到本文的主题:autoCreateTopicEnable,开启自动创建主题,试想一下,如果生产者向一个不存在的主题发送消息时,上面的任何一个步骤都无法获取到路由信息,那该如何处理这种情况呢?

在RocketMQ中,如果autoCreateTopicEnable设置为true,消息发送者向NameServer查询主题的路由消息返回空时,会尝试用一个系统默认的主题名称(MixAll.AUTO_CREATE_TOPIC_KEY_TOPIC),此时消息发送者得到的路由信息为:

默认Topic在集群的每一台Broker上创建8个队列,那问题来了,为啥新创建的Topic只在一个Broker上创建4个队列呢?

3.2 探究autoCreateTopicEnable机制

3.2.1 默认Topic路由创建机制

温馨提示:本文不会详细跟踪整个创建过程,只会点出源码的关键入口点,如想详细了解NameServer路由消息、消息发送高可用的实现原理,建议查阅笔者的书籍《RocketMQ技术内幕》第二、三章。

Step1:在Broker启动流程中,会构建TopicConfigManager对象,其构造方法中首先会判断是否开启了允许自动创建主题,如果启用了自动创建主题,则向topicConfigTable中添加默认主题的路由信息。

TopicConfigManager构造方法

备注:该topicConfigTable中所有的路由信息,会随着Broker向Nameserver发送心跳包中,Nameserver收到这些信息后,更新对应Topic的路由信息表。

BrokerConfig的defaultTopicQueueNum默认为8。两台Broker服务器都会运行上面的过程,故最终Nameserver中关于默认主题的路由信息中,会包含两个Broker分别各8个队列信息。

Step2:生产者寻找路由信息
生产者首先向NameServer查询路由信息,由于是一个不存在的主题,故此时返回的路由信息为空,RocketMQ会使用默认的主题再次寻找,由于开启了自动创建路由信息,NameServer会向生产者返回默认主题的路由信息。然后从返回的路由信息中选择一个队列(默认轮询)。消息发送者从Nameserver获取到默认的Topic的队列信息后,队列的个数会改变吗?答案是会的,其代码如下:

MQClientInstance#updateTopicRouteInfoFromNameServer

温馨提示:消息发送者在到默认路由信息时,其队列数量,会选择DefaultMQProducer#defaultTopicQueueNums与Nameserver返回的的队列数取最小值,DefaultMQProducer#defaultTopicQueueNums默认值为4,故自动创建的主题,其队列数量默认为4。

Step3:发送消息

DefaultMQProducerImpl#sendKernelImpl

在消息发送时的请求报文中,设置默认topic名称,消息发送topic名称,使用的队列数量为DefaultMQProducer#defaultTopicQueueNums,即默认为4。

Step4:Broker端收到消息后的处理流程
服务端收到消息发送的处理器为:SendMessageProcessor,在处理消息发送时,会调用super.msgCheck方法:

AbstractSendMessageProcessor#msgCheck

在Broker端,首先会使用TopicConfigManager根据topic查询路由信息,如果Broker端不存在该主题的路由配置(路由信息),此时如果Broker中存在默认主题的路由配置信息,则根据消息发送请求中的队列数量,在Broker创建新Topic的路由信息。这样Broker服务端就会存在主题的路由信息。

在Broker端的topic配置管理器中存在的路由信息,一会向Nameserver发送心跳包,汇报到Nameserver,另一方面会有一个定时任务,定时存储在broker端,具体路径为${ROCKET_HOME}/store/config/topics.json中,这样在Broker关闭后再重启,并不会丢失路由信息。

广大读者朋友,跟踪到这一步的时候,大家应该对启用自动创建主题机制时,新主题的路由信息是如何创建的,为了方便理解,给出创建主题序列图:

3.2.2 现象分析

经过上面自动创建路由机制的创建流程,我们可以比较容易的分析得出如下结论:

因为开启了自动创建路由信息,消息发送者根据Topic去NameServer无法得到路由信息,但接下来根据默认Topic从NameServer是能拿到路由信息(在每个Broker中,存在8个队列),因为两个Broker在启动时都会向NameServer汇报路由信息。此时消息发送者缓存的路由信息是2个Broker,每个Broker默认4个队列(原因见3.2.1:Step2的分析)。

消息发送者然后按照轮询机制,发送第一条消息选择(broker-a的messageQueue:0),向Broker发送消息,Broker服务器在处理消息时,首先会查看自己的路由配置管理器(TopicConfigManager)中的路由信息,此时不存在对应的路由信息,然后尝试查询是否存在默认Topic的路由信息,如果存在,说明启用了autoCreateTopicEnable,则在TopicConfigManager中创建新Topic的路由信息,此时存在与Broker服务端的内存中,然后本次消息发送结束。此时,在NameServer中还不存在新创建的Topic的路由信息。

这里有三个关键点:

  1. 启用autoCreateTopicEnable创建主题时,在Broker端创建主题的时机为,消息生产者往Broker端发送消息时才会创建。

  2. 然后Broker端会在一个心跳包周期内,将新创建的路由信息发送到NameServer,于此同时,Broker端还会有一个定时任务,定时将内存中的路由信息,持久化到Broker端的磁盘上。

  3. 消息发送者会每隔30s向NameServer更新路由信息,如果消息发送端一段时间内未发送消息,就不会有消息发送集群内的第二台Broker,那么NameServer中新创建的Topic的路由信息只会包含Broker-a,然后消息发送者会向NameServer拉取最新的路由信息,此时就会消息发送者原本缓存了2个broker的路由信息,将会变为一个Broker的路由信息,则该Topic的消息永远不会发送到另外一个Broker,就出现了上述现象。

原因就分析到这里了,现在我们还可以的大胆假设,开启autoCreateTopicEnable机制,什么情况会在两个Broker上都创建队列,其实,我们只需要连续快速的发送9条消息,就有可能在2个Broker上都创建队列,验证代码如下:

验证结果如图所示:

作者简介:丁威,CSDN 博客专家,《RocketMQ技术内幕》作者,维护公众号”中间件兴趣圈“。目前就职于中通科技技术平台部,担任架构师,负责消息中间件、全链路压测的落地工作。

Python这么强大, 怎样快速学习?

https://edu.csdn.net/topic/python115?utm_source=csdn_bw

【End】

 热 文 推 荐 

☞Google 向平板电脑彻底说再见!

☞直接拿来用!Visual Studio 扩展工具利用 AI 强化你的代码

☞苹果召回6.3万台MacBook Pro;罗永浩回应“收购苹果”;新版Edge支持Windows 7/8 | 极客头条

☞10分钟读懂什么是容器云?

☞媲美Pandas?Python的Datatable包怎么用?

☞西交出身,辛书冕获CVPR 2019最佳论文,李飞飞团队获经典论文奖

☞倒计时10天 | 堪称年度中国最具影响力的以太坊技术盛宴,为何不容错过?

☞技术面试别扯智力题!

☞她说:程序员离开电脑就是 “废物” !

你点的每个“在看”,我都认真当成了喜欢

生产环境下 RocketMQ 为什么不能开启自动创建主题?相关推荐

  1. SQL Server大负载的生产环境下的性能优化:初识元数据优化

    相信朋友对SQL Server性能调优相关的知识或多或少都有一些了解.虽然说现在NOSQL相关的技术非常的火热,但是RMDB(关系型数据库)与NOSQL是并存的,并且适用在各种的项目中.在一般的企业级 ...

  2. 生产环境下的LAMP环境搭建

    生产环境下的LAMP环境搭建 V20 学习猿地  ww.lmonkey.com 一.LAMP环境介绍 Web服务器的主要功能是提供网上信息浏览服务.所有网页的集合被称为网站,网站也只有发布到网上才能被 ...

  3. Dapper--Google生产环境下的分布式跟踪系统

    Dapper--Google生产环境下的分布式跟踪系统 概述 当代的互联网的服务,通常都是用复杂的.大规模分布式集群来实现的.互联网应用构建在不同的软件模块集上,这些软件模块,有可能是由不同的团队开发 ...

  4. 在生产环境下处理EFCore数据库迁移的五种方法

    在生产环境下处理EFCore数据库迁移的五种方法 原文链接:https://www.thereformedprogrammer.net/handling-entity-framework-core-d ...

  5. Java生产环境下性能监控与调优详解 大纲 学习感悟

    Java生产环境下性能监控与调优详解 生产环境发生了内存溢出如何处理? 生产环境应该给服务器分配多少内存合适? 如何对垃圾收集器的性能进行调优? 4.生产环境CPU负载飙高该如何处理? 5.生产环境应 ...

  6. Python开发【项目】:生产环境下实时统计网站访问日志信息

    日志实时分析系统 生产环境下有需求:要每搁五分钟统计下这段时间内的网站访问量.UV.独立IP等信息,用直观的数据表格表现出来 环境描述: 网站为Nginx服务,系统每日凌晨会对日志进行分割,拷贝到其他 ...

  7. 生产环境下JAVA进程高CPU占用故障排查

    感谢原作者 http://blog.chinaunix.net/uid-10449864-id-3463151.html 问题描述: 生产环境下的某台tomcat7服务器,在刚发布时的时候一切都很正常 ...

  8. 生产环境下,oracle不同用户间的数据迁移。第一部分

    :任务名称:生产环境下schema ELON数据迁移至schema TIAN ######################################## 测试一:测试参数 数据泵数据导出: ex ...

  9. 四步法分析定位生产环境下MySQL上千条SQL中的问题所在

    第一步:通过以下两种方式之一来打开慢查询功能 (1)方式一:通过修改mysql的my.cnf文件 如果是5.0或5.1等版本需要增加以下选项: log-slow-queries="mysql ...

最新文章

  1. cad 关键字被保留了?选择集关键字保留了? N S W E关键字无法用?
  2. FastDFS蛋疼的集群和负载均衡(十五)之lvs四层+Nginx七层负载均衡
  3. Access update的时候传递参数的顺序
  4. 华为p4支持鸿蒙功能吗_华为鸿蒙系统可以用了,支持这四款手机,看看有你的吗?...
  5. 数学的意蕴与价值(建议收藏)
  6. 11月AI大事件回顾:GPT3开放使用/女娲视觉大模型/AE文艺复兴/...
  7. 自学php【二】 PHP计算时间加一天
  8. JPA通用Dao类设计
  9. oracle导出报错04063,Oracle EXP导出报错的解决方法
  10. 隐藏 console 窗口
  11. [转载]如何学习ANSYS?
  12. 关于Excel常用函数做数据分析
  13. Java工程师技术栈
  14. 利用Photos 框架搭建美图秀秀相册选择器
  15. 中国紧急警报系统(EAS)行业发展现状与前景动态预测报告2022-2027
  16. 洛谷题集——乒乓球(思维、乒乓球比赛规则)
  17. 【STC单片机学习】第九课:单片机按键使用
  18. 遥感图像超分辨重建综述
  19. ESP8266开发之旅 基础篇⑤ ESP8266 SPI通信和I2C通信
  20. TestCenter测试管理工具功能详解十二(Q)

热门文章

  1. linux环境下安装OpenGL
  2. 【ubuntu】查看服务器上的进程占用GPU情况
  3. 不失真截取PDF中的矢量图到Word里
  4. python list切片步长
  5. 计算机控制系统的实时控制应用,计算机控制系统实时性的提高策略
  6. 中国料斗秤行业市场供需与战略研究报告
  7. 2021年中国带锯机市场趋势报告、技术动态创新及2027年市场预测
  8. 2019级C语言大作业 - 冷冻双侠
  9. 第5章 见缝插针(《C和C++游戏趣味编程》配套教学视频)
  10. 第13章 图像像素采样(《Python趣味创意编程》教学视频)