第七章-Broker-创建topic

2024-03-28 20:44
文章标签 创建 第七章 broker topic

本文主要是介绍第七章-Broker-创建topic,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

概念就不讲了,直接上操作和源码,这里就用rocketmq自带的dashboard来创建topic,如下图:

在这里插入图片描述

clusterName:Broker的集群,可以选择多个

BROKER_NAME:Broker 名字,可以选择多个

topicName:topic 名字

writeQueueNums:写队列数

readQueueNums:读队列数

perm:设置topic的读写模式

最终创建topic的方法,由DefaultMQAdminExt.createAndUpdateTopicConfig实现,那么我们顺着这个调用链走下去

DefaultMQAdminExt.createAndUpdateTopicConfig

->DefaultMQAdminExtImpl.createAndUpdateTopicConfig

->MQClientAPIImpl.createTopic

MQClientAPIImpl.createTopic

/**
* 先讲下各个参数代表什么
* addr:选择的单个broker的地址,注意这里是单个,当选择多个broker时,会遍历一个一个的调用创建
* defaultTopic:默认topic => TBW102
* topicConfig:读写队列数、权限等信息
* timeoutMillis:超过毫秒,默认20000
*/
public void createTopic(final String addr, final String defaultTopic, final TopicConfig topicConfig,final long timeoutMillis)throws RemotingException, MQBrokerException, InterruptedException, MQClientException {// 组装请求头CreateTopicRequestHeader requestHeader = new CreateTopicRequestHeader();requestHeader.setTopic(topicConfig.getTopicName());requestHeader.setDefaultTopic(defaultTopic);requestHeader.setReadQueueNums(topicConfig.getReadQueueNums());requestHeader.setWriteQueueNums(topicConfig.getWriteQueueNums());requestHeader.setPerm(topicConfig.getPerm());requestHeader.setTopicFilterType(topicConfig.getTopicFilterType().name());requestHeader.setTopicSysFlag(topicConfig.getTopicSysFlag());requestHeader.setOrder(topicConfig.isOrder());// 主要就看这一行,将请求组装成远程命令对象,请求码为 RequestCode.UPDATE_AND_CREATE_TOPIC,在RocketMQ中,所有的网络请求最终都会转化成对应的请求码,所以我们找到处理该请求码的代码就行,翻看源码得知,这里就得转到broker模块,并由AdminBrokerProcessor.processRequest中处理,且该方法中对应 RequestCode.UPDATE_AND_CREATE_TOPIC 请求码的方法是 updateAndCreateTopic(ctx, request),好了,这下我们直接进入该方法就行。RemotingCommand request = RemotingCommand.createRequestCommand(RequestCode.UPDATE_AND_CREATE_TOPIC, requestHeader);RemotingCommand response = this.remotingClient.invokeSync(MixAll.brokerVIPChannel(this.clientConfig.isVipChannelEnabled(), addr),request, timeoutMillis);assert response != null;switch (response.getCode()) {case ResponseCode.SUCCESS: {return;}default:break;}throw new MQClientException(response.getCode(), response.getRemark());
}

AdminBrokerProcessor.updateAndCreateTopic

private synchronized RemotingCommand updateAndCreateTopic(ChannelHandlerContext ctx,RemotingCommand request) throws RemotingCommandException {// 先创建响应命令对象final RemotingCommand response = RemotingCommand.createResponseCommand(null);// 这里就是转换成当前能识别的,有兴趣的可以进去看看final CreateTopicRequestHeader requestHeader =(CreateTopicRequestHeader) request.decodeCommandCustomHeader(CreateTopicRequestHeader.class);log.info("updateAndCreateTopic called by {}", RemotingHelper.parseChannelRemoteAddr(ctx.channel()));// 检查 topic 名是否与 broker 集群名字冲突,有冲突就要返回错误if (requestHeader.getTopic().equals(this.brokerController.getBrokerConfig().getBrokerClusterName())) {String errorMsg = "the topic[" + requestHeader.getTopic() + "] is conflict with system reserved words.";log.warn(errorMsg);response.setCode(ResponseCode.SYSTEM_ERROR);response.setRemark(errorMsg);return response;}try {// 上面检查通过了,设置返回码为成功response.setCode(ResponseCode.SUCCESS);// 唯一标识当前请求的idresponse.setOpaque(request.getOpaque());response.markResponseType();response.setRemark(null);ctx.writeAndFlush(response);// 将响应信息通过netty写回客户端} catch (Exception e) {log.error("Failed to produce a proper response", e);}// 设置topicConfigTopicConfig topicConfig = new TopicConfig(requestHeader.getTopic());topicConfig.setReadQueueNums(requestHeader.getReadQueueNums());topicConfig.setWriteQueueNums(requestHeader.getWriteQueueNums());topicConfig.setTopicFilterType(requestHeader.getTopicFilterTypeEnum());topicConfig.setPerm(requestHeader.getPerm());topicConfig.setTopicSysFlag(requestHeader.getTopicSysFlag() == null ? 0 : requestHeader.getTopicSysFlag());// 正式存放 topic的操作在这里,看 TopicConfigManager.updateTopicConfigthis.brokerController.getTopicConfigManager().updateTopicConfig(topicConfig);
// 将 broker 的信息再注册到 namesrvthis.brokerController.registerIncrementBrokerData(topicConfig,this.brokerController.getTopicConfigManager().getDataVersion());return null;
}

TopicConfigManager.updateTopicConfig

public void updateTopicConfig(final TopicConfig topicConfig) {// 先在缓存 map中设置 topic的配置TopicConfig old = this.topicConfigTable.put(topicConfig.getTopicName(), topicConfig);if (old != null) {log.info("update topic config, old:[{}] new:[{}]", old, topicConfig);} else {log.info("create new topic [{}]", topicConfig);}// 记录操作版本,其实就是id自增this.dataVersion.nextVersion();// 将topic配置信息持久化到文件this.persist();
}

将topic配置信息持续化到文件

持久化操作在ConfigManager类中执行

public synchronized void persist() {// encode是一个模板方法,由子类实现,在这里指的是 TopicConfigManagerString jsonString = this.encode(true);if (jsonString != null) {// 拿到topic文件存放目录,默认情况下是:{user.home}/store/config/topics.jsonString fileName = this.configFilePath();try {// 将 json 字符串写入 topic 配置文件中,格式如`图7-1`MixAll.string2File(jsonString, fileName);} catch (IOException e) {log.error("persist file " + fileName + " exception", e);}}
}public abstract String encode(final boolean prettyFormat);

TopicConfigManager.encode

public String encode(final boolean prettyFormat) {// 这个方法挺简单,就是把刚才在 updateTopicConfig 方法中存放在本地缓存 map中的值设置到 topicConfigSerializeWrapper对象,同时,将 dataVersion 也设置进去,然后再将对象序列化成 json 字符串TopicConfigSerializeWrapper topicConfigSerializeWrapper = new TopicConfigSerializeWrapper();topicConfigSerializeWrapper.setTopicConfigTable(this.topicConfigTable);topicConfigSerializeWrapper.setDataVersion(this.dataVersion);// 生成 json,格式如`图7-1`return topicConfigSerializeWrapper.toJson(prettyFormat);
}

图7-1

在这里插入图片描述

这篇关于第七章-Broker-创建topic的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/856654

相关文章

Java 虚拟线程的创建与使用深度解析

《Java虚拟线程的创建与使用深度解析》虚拟线程是Java19中以预览特性形式引入,Java21起正式发布的轻量级线程,本文给大家介绍Java虚拟线程的创建与使用,感兴趣的朋友一起看看吧... 目录一、虚拟线程简介1.1 什么是虚拟线程?1.2 为什么需要虚拟线程?二、虚拟线程与平台线程对比代码对比示例:三

k8s按需创建PV和使用PVC详解

《k8s按需创建PV和使用PVC详解》Kubernetes中,PV和PVC用于管理持久存储,StorageClass实现动态PV分配,PVC声明存储需求并绑定PV,通过kubectl验证状态,注意回收... 目录1.按需创建 PV(使用 StorageClass)创建 StorageClass2.创建 PV

Linux创建服务使用systemctl管理详解

《Linux创建服务使用systemctl管理详解》文章指导在Linux中创建systemd服务,设置文件权限为所有者读写、其他只读,重新加载配置,启动服务并检查状态,确保服务正常运行,关键步骤包括权... 目录创建服务 /usr/lib/systemd/system/设置服务文件权限:所有者读写js,其他

idea+spring boot创建项目的搭建全过程

《idea+springboot创建项目的搭建全过程》SpringBoot是Spring社区发布的一个开源项目,旨在帮助开发者快速并且更简单的构建项目,:本文主要介绍idea+springb... 目录一.idea四种搭建方式1.Javaidea命名规范2JavaWebTomcat的安装一.明确tomcat

Git打标签从本地创建到远端推送的详细流程

《Git打标签从本地创建到远端推送的详细流程》在软件开发中,Git标签(Tag)是为发布版本、标记里程碑量身定制的“快照锚点”,它能永久记录项目历史中的关键节点,然而,仅创建本地标签往往不够,如何将其... 目录一、标签的两种“形态”二、本地创建与查看1. 打附注标http://www.chinasem.cn

Spring创建Bean的八种主要方式详解

《Spring创建Bean的八种主要方式详解》Spring(尤其是SpringBoot)提供了多种方式来让容器创建和管理Bean,@Component、@Configuration+@Bean、@En... 目录引言一、Spring 创建 Bean 的 8 种主要方式1. @Component 及其衍生注解

MySQL 数据库表操作完全指南:创建、读取、更新与删除实战

《MySQL数据库表操作完全指南:创建、读取、更新与删除实战》本文系统讲解MySQL表的增删查改(CURD)操作,涵盖创建、更新、查询、删除及插入查询结果,也是贯穿各类项目开发全流程的基础数据交互原... 目录mysql系列前言一、Create(创建)并插入数据1.1 单行数据 + 全列插入1.2 多行数据

MySQL 临时表创建与使用详细说明

《MySQL临时表创建与使用详细说明》MySQL临时表是存储在内存或磁盘的临时数据表,会话结束时自动销毁,适合存储中间计算结果或临时数据集,其名称以#开头(如#TempTable),本文给大家介绍M... 目录mysql 临时表详细说明1.定义2.核心特性3.创建与使用4.典型应用场景5.生命周期管理6.注

MySQL的触发器全解析(创建、查看触发器)

《MySQL的触发器全解析(创建、查看触发器)》MySQL触发器是与表关联的存储程序,当INSERT/UPDATE/DELETE事件发生时自动执行,用于维护数据一致性、日志记录和校验,优点包括自动执行... 目录触发器的概念:创建触www.chinasem.cn发器:查看触发器:查看当前数据库的所有触发器的定

创建springBoot模块没有目录结构的解决方案

《创建springBoot模块没有目录结构的解决方案》2023版IntelliJIDEA创建模块时可能出现目录结构识别错误,导致文件显示异常,解决方法为选择模块后点击确认,重新校准项目结构设置,确保源... 目录创建spChina编程ringBoot模块没有目录结构解决方案总结创建springBoot模块没有目录