Namesrv就是RMQ中的路由服务,可以类比ZK在Kafka中的作用,实现了路由管理、服务注册、服务发现等功能;不过Namesrv相比zookeeper来得要更轻便一点。
一、功能
Namesrv的功能大概可以总结为下面2点:
- 接收broker的请求注册broke路由信息(包括master和slave):broker启动时向所有NameSrv注册,Producer在发送消息前先从Namesrv获取Broker服务器地址列表,通过负载算法选择对应服务器进行消息发送。Namesrv与每台broker保持长连接并进行间隔30s的心跳检测,broker宕机则从路由注册表中删除。
- 接收client的请求根据某个topic获取所有到broker的路由信息
二、启动流程
step1:解析配置文件,填充NameServerConfig,NettyServerConfig属性值
final NamesrvConfig namesrvConfig = new NamesrvConfig();
//这一行是在我本机运行源码demo所设置的RocketmqHome的值
namesrvConfig.setRocketmqHome("F:/J.Howie/rocketmq");
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));
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();
}
}
if (commandLine.hasOption('p')) {
InternalLogger console = InternalLoggerFactory.getLogger(LoggerName.NAMESRV_CONSOLE_NAME);
MixAll.printObjectProperties(console, namesrvConfig);
MixAll.printObjectProperties(console, nettyServerConfig);
System.exit(0);
}
MixAll.properties2Object(ServerUtil.commandLine2Properties(commandLine), namesrvConfig);
先创建NameServerConfig(Namesrv业务参数),NettyServerConfig(Namesrv网络参数),然后再启动时把指定的配置文件或启动命令中的选项值填充到对象中。
- -c configFile 通过-c 命令指定配置文件的路劲
- 使用 “-- 属性名 属性值”,例如 --listenPort 9876
Step2:根据启动属性创建NamesrvController实例,并初始化该实例(step1中的2官网config都是NamesrvController的属性),NamesrvController实例即Namesrv核心控制器
public boolean initialize() {
this.kvConfigManager.load();
//创建NettyServer网络处理对象
this.remotingServer = new NettyRemotingServer(this.nettyServerConfig, this.brokerHousekeepingService);
this.remotingExecutor =
Executors.newFixedThreadPool(nettyServerConfig.getServerWorkerThreads(), new ThreadFactoryImpl("RemotingExecutorThread_"));
this.registerProcessor();
//心跳1:每隔10s扫描一次Broker,移除处于不激活状态的broker
this.scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
NamesrvController.this.routeInfoManager.scanNotActiveBroker();
}
}, 5, 10, TimeUnit.SECONDS);
//心跳2:每隔10min打印一次kv配置
this.scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
NamesrvController.this.kvConfigManager.printAllPeriodically();
}
}, 1, 10, TimeUnit.MINUTES);
return true;
}
Step3:注册JVM钩子函数并启动服务器,以便监听broker、消息生产者的网络请求