NameServer是RocketMQ的路由管理、服务注册与服务发现中心,首先简要说明一下NameServer的主要功能:
- 所有的Broker服务器会向所有的nameServer注册自己的信息
- 消息生产者(Producer)在发送消息时,也会向NameServer请求Broker服务器的地址信息,然后从中选择一台broker服务器进行消息发送
- NameServer会与Broker服务器保持一个连接,接收Broker定时发送回来的心跳信息,如果超过一定时间没收到心跳,那么NameServer将会删除该Broker的路由注册信息,但是有一点要注意,NameServer在删除了某个Broker服务器的路由信息后,并不会主动去通知消息生产者producer,producer自己有一套机制去发现发送消息的Broker服务器已失效,后续在解析生产者代码时会解析。
- 消费者在消费消息之前,也需要向NameServer请求当前存在的Broker服务器,从而进行消息的订阅与消费
NameServer的启动
NameServer的主要功能都在NamesrvController类中,该类内定义了如下的对象,大致罗列了所有对象的基本功能:
//日志
private static final InternalLogger log = InternalLoggerFactory.getLogger(LoggerName.NAMESRV_LOGGER_NAME);
//NameServer的配置信息
private final NamesrvConfig namesrvConfig;
//NameServer模块内嵌的Netty服务器的参数
private final NettyServerConfig nettyServerConfig;
//线程池,用于运行一些定时任务
private final ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(new ThreadFactoryImpl(
"NSScheduledThread"));
//维护NameServer的一些k-v键值对
private final KVConfigManager kvConfigManager;
//维护NameServer的所有路由信息,包括topic的队列信息、Broker的地址等
private final RouteInfoManager routeInfoManager;
//NameServer用于收发消息,接受连接请求的Netty服务器,
private RemotingServer remotingServer;
//处理Broker与NameServer连接状态的一些响应函数
private BrokerHousekeepingService brokerHousekeepingService;
//处理接收到消息的线程池,该线程池执行的代码在对应的processor中
private ExecutorService remotingExecutor;
//NameServer的配置信息类,包括NameServer和NettyServer信息的持久化保存
private Configuration configuration;
//检测认证文件的服务
private FileWatchService fileWatchService;
NameServer启动时,首先通过createNamesrvController方法创建一个NamesrvController对象,后续的所有操作都是通过该对象来进行。NamesrvController首先调用initialize方法完成对象的初始化,主要包括:
-
this.kvConfigManager.load();
加载键值对文件 -
this.remotingServer = new NettyRemotingServer(this.nettyServerConfig, this.brokerHousekeepingService);
创建Netty服务器,在创建该服务器时,会传入一个BrokerHouseKeepingService对象,该对象首先了一系列channel状态变化时的响应函数,这样在Broker服务器与NameServer网络连接状态发生变化时,BrokerHouseKeepingService对象对应的响应方法将会执行。 -
创建线程池,并定义了两个定时操作,分别是扫描失活的broker服务器和打印NameServer维护的键值对信息。
this.remotingExecutor =
Executors.newFixedThreadPool(nettyServerConfig.getServerWorkerThreads(), new ThreadFactoryImpl("RemotingExecutorThread_"));
this.registerProcessor();
this.scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
NamesrvController.this.routeInfoManager.scanNotActiveBroker();
}
}, 5, 10, TimeUnit.SECONDS);
this.scheduledExecutorService.scheduleAtFixedRate(new Runnable(