Talk about nacos' local configinfo processor

Posted by szms on Tue, 15 Oct 2019 16:29:05 +0200

order

This paper focuses on the local configinfo processor of nacos

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;
        }
    }

    /**
     * Gets the contents of the local cache file. NULL means there is no local file or an exception is thrown.
     */
    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);
            }
        }
    }

    /**
     * Clear all cached files in the snapshot directory.
     */
    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);
    }

}
  • The getFailover method first obtains the local configuration file through getFailoverFile, and then reads it through readFile; the getSnapshot method first obtains the snapshot file through getSnapshotFile, and then reads it through readFile; the saveSnapshot method stores the new config; the cleanAllSnapshot method clears all cache files under the snapshot directory

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;
    }

	//......
}
  • The constructor of CacheData will load the cache data from the local disk through loadCacheContentFromDiskLocal; the loadCacheContentFromDiskLocal method will get the data through LocalConfigInfoProcessor.getFailover or LocalConfigInfoProcessor.getSnapshot

Summary

The getFailover method of LocalConfigInfoProcessor first obtains the local configuration file through getFailoverFile, and then reads it through readFile; the getSnapshot method first obtains the snapshot file through getSnapshotFile, and then reads it through readFile; the saveSnapshot method stores the new config; the cleanAllSnapshot method clears all cache files under the snapshot directory

doc

Topics: Programming snapshot Java