乐趣区

关于rocketmq:RocketMQ源码分析1NameServer启动

1.NameServer 是什么?

NameServer 是一个非常简单的 Topic 路由注册核心,其角色相似 Dubbo 中的 zookeeper,反对 Broker 的动静注册与发现。次要包含两个性能:

Broker 治理,NameServer 承受 Broker 集群的注册信息并且保留下来作为路由信息的根本数据。而后提供心跳检测机制,查看 Broker 是否还存活;
路由信息管理,每个 NameServer 将保留对于 Broker 集群的整个路由信息和用于客户端查问的队列信息。而后 Producer 和 Conumser 通过 NameServer 就能够晓得整个 Broker 集群的路由信息,从而进行音讯的投递和生产。NameServer 通常也是集群的形式部署,各实例间互相不进行信息通信。Broker 是向每一台 NameServer 注册本人的路由信息,所以每一个 NameServer 实例下面都保留一份残缺的路由信息。当某个 NameServer 因某种原因下线了,Broker 依然能够向其它 NameServer 同步其路由信息,Producer 和 Consumer 依然能够动静感知 Broker 的路由的信息

2.NameServer 启动入口类
public class NamesrvStartup {

private static InternalLogger log;
private static Properties properties = null;
private static CommandLine commandLine = null;

public static void main(String[] args) {main0(args);
}

public static NamesrvController main0(String[] args) {

    try {NamesrvController controller = createNamesrvController(args);
        //TODO:NameServer 启动
        start(controller);
        String tip = "The Name Server boot success. serializeType=" + RemotingCommand.getSerializeTypeConfigInThisServer();
        log.info(tip);
        System.out.printf("%s%n", tip);
        return controller;
    } catch (Throwable e) {e.printStackTrace();
        System.exit(-1);
    }

    return null;
}

复制代码
晓得了入口,那接下来咱们就剖析下它是如何启动的,启动的过程中都做了什么? 从下面的局部代码中,不难看出,它首先就是创立 NamesrvController 对象,而后启动 (start() 办法),那咱们就一步一步走进去看看细节.
3. 创立 NamesrvController 对象

不要看代码比拟多,其实次要就是创立 3 个对象, 请往后看

public static NamesrvController createNamesrvController(String[] args) throws IOException, JoranException {

System.setProperty(RemotingCommand.REMOTING_VERSION_KEY, Integer.toString(MQVersion.CURRENT_VERSION));
//PackageConflictDetect.detectFastjson();

Options options = ServerUtil.buildCommandlineOptions(new Options());
commandLine = ServerUtil.parseCmdLine("mqnamesrv", args, buildCommandlineOptions(options), new PosixParser());
if (null == commandLine) {System.exit(-1);
    return null;
}

//TODO: 创立 NamesrvConfig 对象
final NamesrvConfig namesrvConfig = new NamesrvConfig();
//TODO: 创立 NettyServerConfig 对象
final NettyServerConfig nettyServerConfig = new NettyServerConfig();
//TODO: 设置固定端口号 9876,客户端连贯的时候就是 nameserverip:9876
nettyServerConfig.setListenPort(9876);
//TODO: 读取命令行中 -c 参数值(如果指定该参数,它是一个配置文件)
if (commandLine.hasOption('c')) {String file = commandLine.getOptionValue('c');
    if (file != null) {InputStream in = new BufferedInputStream(new FileInputStream(file));
        properties = new Properties();
        properties.load(in);
        MixAll.properties2Object(properties, namesrvConfig);
        MixAll.properties2Object(properties, nettyServerConfig);

        namesrvConfig.setConfigStorePath(file);

        System.out.printf("load config properties file OK, %s%n", file);
        in.close();}
}

//TODO: 判断是否有 -p 参数值
if (commandLine.hasOption('p')) {InternalLogger console = InternalLoggerFactory.getLogger(LoggerName.NAMESRV_CONSOLE_NAME);
    MixAll.printObjectProperties(console, namesrvConfig);
    MixAll.printObjectProperties(console, nettyServerConfig);
    System.exit(0);
}

//TODO: 将命令行参数映射到 NamesrvConfig 类中
MixAll.properties2Object(ServerUtil.commandLine2Properties(commandLine), namesrvConfig);

//TODO: 判断是否指定 ROCKETMQ_HOME, 本地运行时, 必须要指定该值
if (null == namesrvConfig.getRocketmqHome()) {System.out.printf("Please set the %s variable in your environment to match the location of the RocketMQ installation%n", MixAll.ROCKETMQ_HOME_ENV);
    System.exit(-2);
}

LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
JoranConfigurator configurator = new JoranConfigurator();
configurator.setContext(lc);
lc.reset();
configurator.doConfigure(namesrvConfig.getRocketmqHome() + "/conf/logback_namesrv.xml");

log = InternalLoggerFactory.getLogger(LoggerName.NAMESRV_LOGGER_NAME);

MixAll.printObjectProperties(log, namesrvConfig);
MixAll.printObjectProperties(log, nettyServerConfig);

//TODO: 创立  NamesrvController 对象
final NamesrvController controller = new NamesrvController(namesrvConfig, nettyServerConfig);

// remember all configs to prevent discard
controller.getConfiguration().registerConfig(properties);

return controller;

}
复制代码
总结一下就是创立 3 个对象

退出移动版