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:9876nettyServerConfig.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 discardcontroller.getConfiguration().registerConfig(properties);return controller;
}
复制代码
总结一下就是创立3个对象