首先我们先理解nameserver在做什么。简单来说就是一个注册中心,用于管理broker的地址信息和topic的信息,客户端可以通过nameserver获得topic信息,通过topic获取broker相关信息,以及每个broker上topic的queue信息等。也就是说nameserver维护了整个MQ集群的元数据信息,客户端可以通过链接nameserver得到这些信息,以明确将对应的消息发送到哪个broker上去。
NameServer的启动
NamesrvStartup类的main方法:
public static void main(String[] args) {
main0(args);
}
public static NamesrvController main0(String[] args) {
try {
// 构造nameSrv控制器
NamesrvController controller = createNamesrvController(args);
// 启动
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;
}
首先构造NameSrv控制器,然后启动。
先看一下创建方法createNamesrvController:
public static NamesrvController createNamesrvController(String[] args) throws IOException, JoranException {
// 版本号
System.setProperty(RemotingCommand.REMOTING_VERSION_KEY, Integer.toString(MQVersion.CURRENT_VERSION));
//PackageConflictDetect.detectFastjson();
// 初始化参数类 -- 这里加了两个option,-h和-n
Options options = ServerUtil.buildCommandlineOptions(new Options());
// buildCommandlineOptions 加了-c 和 -p
// PosixParser 命令行解释器
commandLine = ServerUtil.parseCmdLine("mqnamesrv", args, buildCommandlineOptions(options), new PosixParser());
if (null == commandLine) {
System.exit(-1);
return null;
}
// 初始化namesrv配置
final NamesrvConfig namesrvConfig = new NamesrvConfig();
// 初始化netty服务配置
final NettyServerConfig nettyServerConfig = new NettyServerConfig();
// 设置netty默认端口9876
nettyServerConfig.setListenPort(9876);
// 查看命令行是否包含-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);
// 将properties中存在的nameSrv配置赋值到对应的配置类中,使用反射setter方法
MixAll.properties2Object(properties, namesrvConfig);
MixAll.properties2Object(properties, nettyServerConfig);
// namesrv设置配置文件路径
namesrvConfig.setConfigStorePath(file);
System.out.printf("load config properties file OK, %s%n", file);
in.close();
}
}
// 如果命令行包含-p参数
if (commandLine.hasOption('p')) {
// 获取控制台logger
InternalLogger console = InternalLoggerFactory.getLogger(LoggerName.NAMESRV_CONSOLE_NAME);
// 打印namesrv配置
MixAll.printObjectProperties(console, namesrvConfig);
// 打印netty服务配置
MixAll.printObjectProperties(console, nettyServerConfig);
// 退出。 也就是说-p参数只打印配置,然后就直接退出
System.exit(0);
}
// 将命令行中的参数补充到namesrv配置中
MixAll.properties2Object(ServerUtil.commandLine2Properties(commandLine), namesrvConfig);
// 判断ROCKET_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_EN