序
本文主要研究一下nacos的LocalConfigInfoProcessor
LocalConfigInfoProcessor
nacos-1.1.3/client/src/main/java/com/alibaba/nacos/client/config/impl/LocalConfigInfoProcessor.java
public class LocalConfigInfoProcessor {
private static final Logger LOGGER = LogUtils.logger(LocalConfigInfoProcessor.class);
static public String getFailover(String serverName, String dataId, String group, String tenant) {
File localPath = getFailoverFile(serverName, dataId, group, tenant);
if (!localPath.exists() || !localPath.isFile()) {
return null;
}
try {
return readFile(localPath);
} catch (IOException ioe) {
LOGGER.error("[" + serverName + "] get failover error, " + localPath, ioe);
return null;
}
}
/**
* 获取本地缓存文件内容。NULL表示没有本地文件或抛出异常。
*/
static public String getSnapshot(String name, String dataId, String group, String tenant) {
if (!SnapShotSwitch.getIsSnapShot()) {
return null;
}
File file = getSnapshotFile(name, dataId, group, tenant);
if (!file.exists() || !file.isFile()) {
return null;
}
try {
return readFile(file);
} catch (IOException ioe) {
LOGGER.error("[" + name + "]+get snapshot error, " + file, ioe);
return null;
}
}
static private String readFile(File file) throws IOException {
if (!file.exists() || !file.isFile()) {
return null;
}
if (JVMUtil.isMultiInstance()) {
return ConcurrentDiskUtil.getFileContent(file, Constants.ENCODE);
} else {
InputStream is = null;
try {
is = new FileInputStream(file);
return IOUtils.toString(is, Constants.ENCODE);
} finally {
try {
if (null != is) {
is.close();
}
} catch (IOException ioe) {
}
}
}
}
static public void saveSnapshot(String envName, String dataId, String group, String tenant, String config) {
if (!SnapShotSwitch.getIsSnapShot()) {
return;
}
File file = getSnapshotFile(envName, dataId, group, tenant);
if (null == config) {
try {
IOUtils.delete(file);
} catch (IOException ioe) {
LOGGER.error("[" + envName + "] delete snapshot error, " + file, ioe);
}
} else {
try {
File parentFile = file.getParentFile();
if (!parentFile.exists()) {
boolean isMdOk = parentFile.mkdirs();
if (!isMdOk) {
LOGGER.error("[{}] save snapshot error", envName);
}
}
if (JVMUtil.isMultiInstance()) {
ConcurrentDiskUtil.writeFileContent(file, config,
Constants.ENCODE);
} else {
IOUtils.writeStringToFile(file, config, Constants.ENCODE);
}
} catch (IOException ioe) {
LOGGER.error("[" + envName + "] save snapshot error, " + file, ioe);
}
}
}
/**
* 清除snapshot目录下所有缓存文件。
*/
static public void cleanAllSnapshot() {
try {
File rootFile = new File(LOCAL_SNAPSHOT_PATH);
File[] files = rootFile.listFiles();
if (files == null || files.length == 0) {
return;
}
for (File file : files) {
if (file.getName().endsWith("_nacos")) {
IOUtils.cleanDirectory(file);
}
}
} catch (IOException ioe) {
LOGGER.error("clean all snapshot error, " + ioe.toString(), ioe);
}
}
static public void cleanEnvSnapshot(String envName) {
File tmp = new File(LOCAL_SNAPSHOT_PATH, envName + "_nacos");
tmp = new File(tmp, "snapshot");
try {
IOUtils.cleanDirectory(tmp);
LOGGER.info("success delete " + envName + "-snapshot");
} catch (IOException e) {
LOGGER.info("fail delete " + envName + "-snapshot, " + e.toString());
e.printStackTrace();
}
}
static File getFailoverFile(String serverName, String dataId, String group, String tenant) {
File tmp = new File(LOCAL_SNAPSHOT_PATH, serverName + "_nacos");
tmp = new File(tmp, "data");
if (StringUtils.isBlank(tenant)) {
tmp = new File(tmp, "config-data");
} else {
tmp = new File(tmp, "config-data-tenant");
tmp = new File(tmp, tenant);
}
return new File(new File(tmp, group), dataId);
}
static File getSnapshotFile(String envName, String dataId, String group, String tenant) {
File tmp = new File(LOCAL_SNAPSHOT_PATH, envName + "_nacos");
if (StringUtils.isBlank(tenant)) {
tmp = new File(tmp, "snapshot");
} else {
tmp = new File(tmp, "snapshot-tenant");
tmp = new File(tmp, tenant);
}
return new File(new File(tmp, group), dataId);
}
public static final String LOCAL_FILEROOT_PATH;
public static final String LOCAL_SNAPSHOT_PATH;
static {
LOCAL_FILEROOT_PATH = System.getProperty("JM.LOG.PATH", System.getProperty("user.home")) + File.separator
+ "nacos" + File.separator + "config";
LOCAL_SNAPSHOT_PATH = System.getProperty("JM.SNAPSHOT.PATH", System.getProperty("user.home")) + File.separator
+ "nacos" + File.separator + "config";
LOGGER.info("LOCAL_SNAPSHOT_PATH:{}", LOCAL_SNAPSHOT_PATH);
}
}
- getFailover方法首先会通过getFailoverFile获取本地配置文件,然后通过readFile读取;getSnapshot方法首先通过getSnapshotFile获取snapshot文件,然后通过readFile读取;saveSnapshot方法会存储新的config;cleanAllSnapshot方法会清除snapshot目录下所有缓存文件
CacheData
nacos-1.1.3/client/src/main/java/com/alibaba/nacos/client/config/impl/CacheData.java
public class CacheData {
//......
public CacheData(ConfigFilterChainManager configFilterChainManager, String name, String dataId, String group) {
if (null == dataId || null == group) {
throw new IllegalArgumentException("dataId=" + dataId + ", group=" + group);
}
this.name = name;
this.configFilterChainManager = configFilterChainManager;
this.dataId = dataId;
this.group = group;
this.tenant = TenantUtil.getUserTenantForAcm();
listeners = new CopyOnWriteArrayList<ManagerListenerWrap>();
this.isInitializing = true;
this.content = loadCacheContentFromDiskLocal(name, dataId, group, tenant);
this.md5 = getMd5String(content);
}
public CacheData(ConfigFilterChainManager configFilterChainManager, String name, String dataId, String group,
String tenant) {
if (null == dataId || null == group) {
throw new IllegalArgumentException("dataId=" + dataId + ", group=" + group);
}
this.name = name;
this.configFilterChainManager = configFilterChainManager;
this.dataId = dataId;
this.group = group;
this.tenant = tenant;
listeners = new CopyOnWriteArrayList<ManagerListenerWrap>();
this.isInitializing = true;
this.content = loadCacheContentFromDiskLocal(name, dataId, group, tenant);
this.md5 = getMd5String(content);
}
private String loadCacheContentFromDiskLocal(String name, String dataId, String group, String tenant) {
String content = LocalConfigInfoProcessor.getFailover(name, dataId, group, tenant);
content = (null != content) ? content
: LocalConfigInfoProcessor.getSnapshot(name, dataId, group, tenant);
return content;
}
//......
}
- CacheData的构造器会通过loadCacheContentFromDiskLocal从本地磁盘加载缓存数据;loadCacheContentFromDiskLocal方法则是通过LocalConfigInfoProcessor.getFailover或LocalConfigInfoProcessor.getSnapshot来获取数据
小结
LocalConfigInfoProcessor的getFailover方法首先会通过getFailoverFile获取本地配置文件,然后通过readFile读取;getSnapshot方法首先通过getSnapshotFile获取snapshot文件,然后通过readFile读取;saveSnapshot方法会存储新的config;cleanAllSnapshot方法会清除snapshot目录下所有缓存文件