NameService架构设计
消息中间件的设计思路一般基于主题的订阅发布机制,消息生产者发送某个主题的消息到服务器,消息服务器负责该消息的持久存储,消费者订阅感兴趣的主题,消息服务器根据订阅信息(路由信息)将消息推送到消费者(push模式)或者消息消费者主动向消息服务器拉取消息(PULL模式),从而实现消息的生产者与消费者解耦。
Prodecer集群:消息发出方 Consumer:集群消息消费方
Booker消费服务器
消息发送需先从NameService获取Broker服务器地址,然后根据负载均衡算法从列表中选择一台消息服务器进行消息发送。
NameService本身的高可用可通过部署多台NameService服务器来实现,但彼此之间互不通信,也就是NameService服务器之间在某一时刻的数据不完全相同。
NameService启动流程
大概流程:NamesrvStartup.Main()->创建NamesrvController对象->调用start(controller)
createNamesrvController方法:主要完成NamesrvConfig,NettyServerConfig的赋值。
参数配置来源存在两处:
1.-c configFile 通过-C命令指定配置文件的路径
2.使用 “–属性名 属性值”例如 --listenport
start(controller)方法:调用了NamesrvController.initialize()主要是加载KV配置,创建NettyServer网格处理对象,然后开启两个定时任务,在RocketMQ中此类定时任务统称为心跳检测
定时任务1.每隔10s扫描一次Broker,移除处于不激活状态的Broker
定时任务2.每隔10分钟答应一次kv配置
创建jvm钩子函数 如果代码使用线程池一定要优雅的停机方式就是注册一个jvm钩子函数,在jvm关闭前先将线程池关闭,及时释放资源
NettyServerConfig.initialize源码:
public boolean initialize() {
this.kvConfigManager.load();
this.remotingServer = new NettyRemotingServer(this.nettyServerConfig, this.brokerHousekeepingService);
this.remotingExecutor =
Executors.newFixedThreadPool(nettyServerConfig.getServerWorkerThreads(), new ThreadFactoryImpl("RemotingExecutorThread_"));
this.registerProcessor();
//每隔10s扫描一次Broker,移除处于不激活状态的Broker
this.scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
NamesrvController.this.routeInfoManager.scanNotActiveBroker();
}
}, 5, 10, TimeUnit.SECONDS);
//.每隔10分钟答应一次kv配置
this.scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
NamesrvController.this.kvConfigManager.printAllPeriodically();
}
}, 1, 10, TimeUnit.MINUTES);
//省略部分代码
return true;
}
NamesrvStartup.start(final NamesrvController controller)源码:
public static NamesrvController start(final NamesrvController controller) throws Exception {
if (null == controller) {
throw new IllegalArgumentException("NamesrvController is null");
}
boolean initResult = controller.initialize();
if (!initResult) {
controller.shutdown();
System.exit(-3);
}
//创建jvm钩子函数 如果代码使用线程池一定要优雅的停机方式就是注册一个jvm钩子函数,在jvm关闭前先将线程池关闭,及时释放资源
Runtime.getRuntime().addShutdownHook(new ShutdownHookThread(log, new Callable<Void>() {
@Override
public Void call() throws Exception {
controller.shutdown();
return null;
}
}));
controller.start();
return controller;
}