NamesrvStartup 是模块的启动人 口, NamesrvController 用来协块各个调模功能的代码
我们从启动代码开始分析,找到 NamesrvStartup.java 里的 main 函数 public static void main(String[] args) {mainO(args );},发现它又把逻辑转到 main0 这个函数里



解析-c、-p参数之后初始化Controller



初始化失败会调用System.exit(-3);退出程序,退出程序前会调用一个shutdown的清理线程的方法,里面有一个实现Calable接口的线程,如果初始化成功controller线程就会start();
下面为初始化源码:


NamesrvController才是总控逻辑,刚才的Controller线程start之后NameServer就没用了,Controller会初始化三个线程池

8个是Netty业务线程池里的线程个数
1个用来定时扫描失效的,一个用来定时打印日志
路由注册
1、路由元信息
RouteInfoManager:
private final static long BROKER_CHANNEL_EXPIRED_TIME = 1000 * 60 * 2;
//可重入读写锁,操作维护元数据信息使用
private final ReadWriteLock lock = new ReentrantReadWriteLock();
//topic信息,Topic名字为key,value的大小等于topic数据存储的master broker个数
//QueuData里包括Broker名称,读队列数量,写队列数量,同步标识
private final HashMap<String/* topic */, List<QueueData>> topicQueueTable;
//broker信息,包含集群名称,broker名称,broker地址(
//Map存储,一主多从,brokerId为key,主都是0,从大于0)
private final HashMap<String/* brokerName */, BrokerData> brokerAddrTable;
//集群信息,一个集群下的所有broker
private final HashMap<String/* clusterName */, Set<String/* brokerName */>> clusterAddrTable;
//类似brokerAddrTable,区别一个在于key,这个key是唯一的,多个集群的brokerName可相同
//这里数据实时,实时更新维护Broker信息,后期会根据这个移除不活动的,超时120未更新
private final HashMap<String/* brokerAddr */, BrokerLiveInfo> brokerLiveTable;
//过滤服务器。服务端过滤。
private final HashMap<String/* brokerAddr */, List<String>/* Filter Server */> filterServerTable;
2、路由注册
前面说到Broker启动后向所有NameServer发送心跳信息,每隔30S发送自己的心跳包,NameServer收到后更新BrokerLiveTable中的BrokerLiveInfo信息。
public static BrokerController start(BrokerController controller) {
//*****省略*********
controller.start();
//*****省略*********
return null;
}
public void start() throws Exception {
//******省略*******
this.registerBrokerAll(true, false, true);
this.scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
try {
BrokerController.this.registerBrokerAll(true, false, brokerConfig.isForceRegister());
} catch (Throwable e) {
log.error("registerBrokerAll Exception", e);
}
}
}, 1000 * 10, Math.max(10000, Math.min(brokerConfig.getRegisterNameServerPeriod(), 60000)), TimeUnit.MILLISECONDS);
//******省略*******
}
NameServer代码简单,没有复杂的重新选举等操作,通过集群来保证可用性,功能简单,但是效率更高。
网友评论