各个角色间的交互流程

        下面从Topic的创建入手,结合源码分析一下NameServer如何和其他各个组件交互,以及NameServer存储的元数据内容的具体含义。

1.交互流程源码分析

        创建Topic的代码是在org.apache.rocketmq.tools.command.topic里的UpdateTopicSubCommand类中,创建Topic的命令是updateTopic如代码清单4-3所示。

代码清单4-3 updateTopic的选项

Option("b", "BrokerAddr", true, "create topic to which Broker");
Option("c", "ClusterName", true, "create topic to which Cluster");
Option("t", "topic", true, "topic name");
Option("r", "readQueueNums", true, "set read queue nums");
Option("w", "writeQueueNums", true, "set write queue nums");
Option("p", "perm", true, "set topic's permission(2|4|6), intro[2:W 4:R; 6:RW]");
Option("o", "order", true, "set topic's order(true|false");
Option("u", "unit", true, "is unit topic (true|false");
Option("s", "hasUnitSub", true, "has unit sub (true|false");

 

其中b和c参数比较重要,而且他们俩只有一个会起作用(-b优先),b参数指定在哪个Broker上创建本Topic的Message Queue,c参数表示在这个Cluster下面所有的Master Broker上创建这个Topic的Message Queue,从而达到高可用性的目的。具体的创建动作是通过发送命令触发的,如代码清单4-4所示。

代码清单4-4 updateTopic的命令

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());

RemotingCommand request = RemotingCommand.createRequestCommand(RequestCode. UPDATE_AND_CREATE_TOPIC, requestHeader)

 

创建Topic的命令被发往对应的Broker,Broker接到创建Topic的请求后,执行具体的创建逻辑,如代码清单4-5所示。

代码清单4-5 Broker处理updateTopic命令

    private RemotingCommand updateAndCreateTopic(ChannelHandlerContext ctx, RemotingCommand request) throws RemotingCommandException {
     ...
this.BrokerController.getTopicConfigManager().updateTopicConfig(topicConfig);  //更新本地的topicConfig
        this.BrokerController.registerBrokerAll(false, true); //向NameServer发送registerBroker请求
        return null;
    }

 

注意最后一步是向NameServer发送注册信息,NameServer完成创建Topic的逻辑后,其他客户端才能发现新增的Topic,相关逻辑在org.apache.rocketmq.namesrv.routeinfo的RouteInfoManager类中的registerBroker函数里,首先更新Broker信息,然后对每个Master角色的Broker,创建一个QueueData对象。如果是新建Topic,就是添加QueueData对象;如果是修改Topic,就是把旧的QueueData删除,加入新的QueueData。

2.为何不用ZooKeeper

        ZooKeeper是Apache的一个开源软件,为分布式应用程序提供协调服务。那为什么RocketMQ要自己造轮子,开发集群的管理程序呢?答案是ZooKeeper的功能很强大,包括自动Master选举等,RocketMQ的架构设计决定了它不需要进行Master选举,用不到这些复杂的功能,只需要一个轻量级的元数据服务器就足够了。中间件对稳定性要求很高,RocketMQ的NameServer只有很少的代码,容易维护,所以不需要再依赖另一个中间件,从而减少整体维护成本。

你可能感兴趣的:(RocketMQ,rocketmq,java-rocketmq,java,后端)