NameServer负责MQ消息的路由。生产者发送消息前,先从NameServer获取broker列表,然后根据负载均衡算法,找到broker发送消息。
NameServer本地启动流程
查看mqnameserv.sh脚本,我们看下核心的启动方法
sh ${ROCKETMQ_HOME}/bin/runserver.sh org.apache.rocketmq.namesrv.NamesrvStartup $@
找到对应的类,启动即可启动本地mq NameServer,不过鉴于本地需要校验NameServer的安装home路径,所以我们直接修改代码:
直接右键启动,报错
Please set the %s variable in your environment to match the location of the RocketMQ installation%n
查看对应的错误源码:
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);
}
我们看到MQ会加载校验对应的RockeMQHome,那么我们可以通过以下几个方式设置:
- 更改源码,写死地址信息
- 通过vm options -Drocketmq.home.dir=/Users/jinglongjun/programe/rocketMQ/release/rocketmq-4.5.2 来指定。
- 设置环境变量 ROCKETMQ_HOME
NameServer 配置文件加载
NamesrvController#createNamesrvController方法
Options options = ServerUtil.buildCommandlineOptions(new Options());
commandLine = ServerUtil.parseCmdLine("mqnamesrv", args, buildCommandlineOptions(options), new PosixParser());
if (null == commandLine) {
System.exit(-1);
return null;
}
final NamesrvConfig namesrvConfig = new NamesrvConfig();
final NettyServerConfig nettyServerConfig = new NettyServerConfig();
nettyServerConfig.setListenPort(9876);
if (commandLine.hasOption('c')) {
String file = commandLine.getOptionValue('c');
if (file != null) {
InputStream in = new BufferedInputStream(new FileInputStream(file));
.....
}
}
if (commandLine.hasOption('p')) {
....
}
通过如上方式我们可以看到不同的加载配置文件的方式。
最终填充两个核心配置:
- NamesrvConfig
- NettyServerConfig
NamesrvConfig的配置信息如下
public class NamesrvConfig {
private String rocketmqHome = System.getProperty(MixAll.ROCKETMQ_HOME_PROPERTY, System.getenv(MixAll.ROCKETMQ_HOME_ENV));
private String kvConfigPath = System.getProperty("user.home") + File.separator + "namesrv" + File.separator + "kvConfig.json";
private String configStorePath = System.getProperty("user.home") + File.separator + "namesrv" + File.separator + "namesrv.properties";
private String productEnvName = "center";
private boolean clusterTest = false;
private boolean orderMessageEnable = false;
属性 | 含义 |
---|---|
rocketmqHome | rocketmq 主目录,可以通过 -Drocketmq.home.dir=path 或通过设置环 境变量 ROCKETMQ_HOME 来配置 RocketMQ 的主目录 |
kvConfigPath | NameServer存储kv配置属性持久化存储的路劲 |
configStorePath | 默认配置文件属性,不生效,如果需要配置文件启动,则可以通过-c参数指定 |
orderMessageEnable | 是否支持顺序消息,默认不支持 |
NettyServerConfig 的配置信息如下:
public class NettyServerConfig implements Cloneable {
private int listenPort = 8888;
private int serverWorkerThreads = 8;
private int serverCallbackExecutorThreads = 0;
private int serverSelectorThreads = 3;
private int serverOnewaySemaphoreValue = 256;
private int serverAsyncSemaphoreValue = 64;
private int serverChannelMaxIdleTimeSeconds = 120;
private int serverSocketSndBufSize = NettySystemConfig.socketSndbufSize;
private int serverSocketRcvBufSize = NettySystemConfig.socketRcvbufSize;
private boolean serverPooledByteBufAllocatorEnable = true;
start(controller);
boolean initResult = controller.initialize();
if (!initResult) {
controller.shutdown();
System.exit(-3);
}
Runtime.getRuntime().addShutdownHook(new ShutdownHookThread(log, new Callable<Void>() {
@Override
public Void call() throws Exception {
controller.shutdown();
return null;
}
}));
controller.start();
initialize
NamesrvController#initialize
- 加载配置文件
- 生成 RemotingServer
- 启动计划任务十秒扫描不活跃的broker
- 启动计划任务十秒打印配置文件
- TLS 模式配置
注册shutdown 函数,监听关闭
start
NamesrvController#start
public void start() throws Exception {
this.remotingServer.start();
if (this.fileWatchService != null) {
this.fileWatchService.start();
}
}