实例列表获取主要是HostReactor#getServiceInfo方法。Nacos - 启动中namingService.subscribe注册监听的时候,也会调用这个方法。
getServiceInfopublic ServiceInfo getServiceInfo(final String serviceName, final String clusters) {
// 如果发生故障转移,就从文件缓存里取
NAMING_LOGGER.debug("failover-mode: " + failoverReactor.isFailoverSwitch());
String key = ServiceInfo.getKey(serviceName, clusters);
if (failoverReactor.isFailoverSwitch()) {
return failoverReactor.getService(key);
}
// 从serviceInfoMap里取
ServiceInfo serviceObj = getServiceInfo0(serviceName, clusters);
// serviceInfoMap没有
if (null == serviceObj) {
serviceObj = new ServiceInfo(serviceName, clusters);
serviceInfoMap.put(serviceObj.getKey(), serviceObj);
updatingMap.put(serviceName, new Object());
// 内存没有,从服务器取
updateServiceNow(serviceName, clusters);
updatingMap.remove(serviceName);
} else if (updatingMap.containsKey(serviceName)) {
// 如果正在更新,则wait,避免多线程同时调用服务器
if (UPDATE_HOLD_INTERVAL > 0) {
// hold a moment waiting for update finish
synchronized (serviceObj) {
try {
serviceObj.wait(UPDATE_HOLD_INTERVAL);
} catch (InterruptedException e) {
NAMING_LOGGER
.error("[getServiceInfo] serviceName:" + serviceName + ", clusters:" + clusters, e);
}
}
}
}
// 开启定时任务更新服务列表
scheduleUpdateIfAbsent(serviceName, clusters);
// 从内存里取
return serviceInfoMap.get(serviceObj.getKey());
}
updateServiceNow
从服务器获取,NamingProxy会调用NamingProxy#reqApi,他会随机取一个server,调用NamingProxy#callServer。NamingProxy的代码就略了。private void updateServiceNow(String serviceName, String