Rocketmq topic 管理及自动创建分析

rocketmq topic 信息是保存在broker 上

  1. borker会定期保存到store/config 下topics.json
  2. 每次broker启动会默认创建系统级topic,其中就有TBW102,此topic的route(配置)将作为sendmessage时候未创建topic的默认route
  3. 禁止自动创建topic方法:可以配置broker的配置autoCreateTopicEnable=false 不创建默认topic达到关闭
// MixAll.AUTO_CREATE_TOPIC_KEY_TOPIC
            if (this.brokerController.getBrokerConfig().isAutoCreateTopicEnable()) {
                String topic = MixAll.AUTO_CREATE_TOPIC_KEY_TOPIC;
                TopicConfig topicConfig = new TopicConfig(topic);
                this.systemTopicList.add(topic);
                topicConfig.setReadQueueNums(this.brokerController.getBrokerConfig()
                    .getDefaultTopicQueueNums());
                topicConfig.setWriteQueueNums(this.brokerController.getBrokerConfig()
                    .getDefaultTopicQueueNums());
                int perm = PermName.PERM_INHERIT | PermName.PERM_READ | PermName.PERM_WRITE;
                topicConfig.setPerm(perm);
                this.topicConfigTable.put(topicConfig.getTopicName(), topicConfig);
            }

通过修改TBW102 PERM为0并且需要注意每个新broker增加的时候都需要设置为0(可以通过复用已经存在的broker存储信息),也可以达到同样目的。
Rocketmq topic 管理及自动创建分析_第1张图片
5. master之间不会同步topic,namesrv上的topic 只作为查询使用

send message 中topic相关关键代码:DefaultMQProducerImpl的 sendDefaultImpl 调用TopicPublishInfo topicPublishInfo = this.tryToFindTopicPublishInfo(msg.getTopic());如果寻找不到当前topic,使用默认topic配置进行发送。

tryToFindTopicPublishInfo代码分析如下:

private TopicPublishInfo tryToFindTopicPublishInfo(final String topic) {
//先看看本地是否有
        TopicPublishInfo topicPublishInfo = this.topicPublishInfoTable.get(topic);
        if (null == topicPublishInfo || !topicPublishInfo.ok()) {
            this.topicPublishInfoTable.putIfAbsent(topic, new TopicPublishInfo());
//从namesrv寻找,新topic将寻找不到,topicPublishInfo.isHaveTopicRouterInfo()为空
            this.mQClientFactory.updateTopicRouteInfoFromNameServer(topic);
            topicPublishInfo = this.topicPublishInfoTable.get(topic);
        }

        if (topicPublishInfo.isHaveTopicRouterInfo() || topicPublishInfo.ok()) {
            return topicPublishInfo;
        } else {
//新topic,没有找到route,进入此处
//   defaultMQProducer -TOPIC TBW102
// Configuration_Client.md createTopicKey                   | TBW102           | When a message is sent, topics that do not exist on the server are automatically created and a Key is specified that can be used to configure the default route to the topic where the message is sent.|
///    DefaultMQProducer.java private String createTopicKey = MixAll.AUTO_CREATE_TOPIC_KEY_TOPIC;
//    public static final String AUTO_CREATE_TOPIC_KEY_TOPIC = "TBW102"; // Will be created at broker when isAutoCreateTopicEnable


           this.mQClientFactory.updateTopicRouteInfoFromNameServer(topic, true, this.defaultMQProducer);
            topicPublishInfo = this.topicPublishInfoTable.get(topic);
            return topicPublishInfo;
        }
    }

如何一路到发送消息

 brokerAddr = MixAll.brokerVIPChannel(this.defaultMQProducer.isSendMessageWithVIPChannel(), brokerAddr);
     
     sendResult = this.mQClientFactory.getMQClientAPIImpl().sendMessage(
                            brokerAddr,
                            mq.getBrokerName(),
                            msg,
                            requestHeader,
                            timeout - costTimeSync,
                            communicationMode,
                            context,
                            this);
发送前没有创建topic,有broker在收到消息后负责创建

broker的具体实现在SendMessageProcessor类的

private RemotingCommand sendMessage(final ChannelHandlerContext ctx,
                                        final RemotingCommand request,
                                        final SendMessageContext sendMessageContext,
                                        final SendMessageRequestHeader requestHeader) throws 
   方法中调用AbstractSendMessageProcessor.msgCheck的过程中实现创建
 log.warn("the topic {} not exist, producer: {}", requestHeader.getTopic(), ctx.channel().remoteAddress());
            topicConfig = this.brokerController.getTopicConfigManager().createTopicInSendMessageMethod(
                requestHeader.getTopic(),
                requestHeader.getDefaultTopic(),
                RemotingHelper.parseChannelRemoteAddr(ctx.channel()),
                requestHeader.getDefaultTopicQueueNums(), topicSysFlag);

            if (null == topicConfig) {
                if (requestHeader.getTopic().startsWith(MixAll.RETRY_GROUP_TOPIC_PREFIX)) {
                    topicConfig =
                        this.brokerController.getTopicConfigManager().createTopicInSendMessageBackMethod(
                            requestHeader.getTopic(), 1, PermName.PERM_WRITE | PermName.PERM_READ,
                            topicSysFlag);
                }
            }

            if (null == topicConfig) {
                response.setCode(ResponseCode.TOPIC_NOT_EXIST);
                response.setRemark("topic[" + requestHeader.getTopic() + "] not exist, apply first please!"
                    + FAQUrl.suggestTodo(FAQUrl.APPLY_TOPIC_URL));
                return response;
            }```

你可能感兴趣的:(Rocketmq)