前言
上文说到 NacosConfigService
会初始化 ServerHttpAgent
,本文接着来讲
ServerHttpAgent初始化
调用有参构造初始化
public ServerHttpAgent(Properties properties) throws NacosException {
//初始化ServerListManager
this.serverListMgr = new ServerListManager(properties);
//初始化SecurityProxy
this.securityProxy = new SecurityProxy(properties, NACOS_RESTTEMPLATE);
//获取namespaceId
this.namespaceId = properties.getProperty(PropertyKeyConst.NAMESPACE);
//调用init方法
init(properties);
//重置登录token
this.securityProxy.login(this.serverListMgr.getServerUrls());
// init executorService
this.executorService = new ScheduledThreadPoolExecutor(1, new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
t.setName("com.alibaba.nacos.client.config.security.updater");
t.setDaemon(true);
return t;
}
});
//定时5毫秒执行一次
this.executorService.scheduleWithFixedDelay(new Runnable() {
@Override
public void run() {
securityProxy.login(serverListMgr.getServerUrls());
}
}, 0, this.securityInfoRefreshIntervalMills, TimeUnit.MILLISECONDS);
}
没什么特别的,接下来看start方法
@Override
public void start() throws NacosException {
serverListMgr.start();
}
/**
* Start.
*
* @throws NacosException nacos exception
*/
public synchronized void start() throws NacosException {
if (isStarted || isFixed) {
return;
}
//新建一个Runnable任务
GetServerListTask getServersTask = new GetServerListTask(addressServerUrl);
for (int i = 0; i < initServerlistRetryTimes && serverUrls.isEmpty(); ++i) {
//调用run方法,此处没有开启线程
getServersTask.run();
try {
this.wait((i + 1) * 100L);
} catch (Exception e) {
LOGGER.warn("get serverlist fail,url: {}", addressServerUrl);
}
}
if (serverUrls.isEmpty()) {
LOGGER.error("[init-serverlist] fail to get NACOS-server serverlist! env: {}, url: {}", name,
addressServerUrl);
throw new NacosException(NacosException.SERVER_ERROR,
"fail to get NACOS-server serverlist! env:" + name + ", not connnect url:" + addressServerUrl);
}
//此处开启了线程,定时任务每30s执行一次
// executor schedules the timer task
this.executorService.scheduleWithFixedDelay(getServersTask, 0L, 30L, TimeUnit.SECONDS);
isStarted = true;
}
主要还是获取naocs-server的serverUrls,看到这里,仍然没有什么特别之处,我们回到NacosConfigService
看 ClientWorker
如何初始化的
ClientWorker初始化
有参构造初始化
public ClientWorker(final HttpAgent agent, final ConfigFilterChainManager configFilterChainManager,
final Properties properties) {
this.agent = agent;
this.configFilterChainManager = configFilterChainManager;
// Initialize the timeout parameter
init(properties);
//初始化线程池
this.executor = Executors.newScheduledThreadPool(1, new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
t.setName("com.alibaba.nacos.client.Worker." + agent.getName());
t.setDaemon(true);
return t;
}
});
//初始化线程池
this.executorService = Executors
.newScheduledThreadPool(Runtime.getRuntime().availableProcessors(), new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
t.setName("com.alibaba.nacos.client.Worker.longPolling." + agent.getName());
t.setDaemon(true);
return t;
}
});
//执行定时任务延迟1ms执行,每10毫秒执行一次
this.executor.scheduleWithFixedDelay(new Runnable() {
@Override
public void run() {
try {
checkConfigInfo();
} catch (Throwable e) {
LOGGER.error("[" + agent.getName() + "] [sub-check] rotate check error", e);
}
}
}, 1L, 10L, TimeUnit.MILLISECONDS);
}
可以看到这里初始化了两个线程池,从线程名字上来看
一个线程是Worker工作线程
一个是longpolling长轮询线程
工作线程 :
/**
* Check config info.
*/
public void checkConfigInfo() {
// Dispatch taskes.
int listenerSize = cacheMap.get().size();
// Round up the longingTaskCount.
int longingTaskCount = (int) Math.ceil(listenerSize / ParamUtil.getPerTaskConfigSize());
if (longingTaskCount > currentLongingTaskCount) {
for (int i = (int) currentLongingTaskCount; i < longingTaskCount; i++) {
// The task list is no order.So it maybe has issues when changing.
executorService.execute(new LongPollingRunnable(i));
}
currentLongingTaskCount = longingTaskCount;
}
}
将listenerSize/3000 向上取整,作为本次长轮询的次数
将LongPollingRunnable
任务放入到长轮询线程池中执行