欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

分布式配置中心超轻量的实现方式(带源码)

程序员文章站 2022-07-15 09:48:13
...

随着微服务成为一种潮流,各种配置也变得越来越烦杂。传统的文本文件的配置方式,已经不能满足现有需求。
缺点如下:

  • 修改配置需要重新打包,发布
  • 对于一些公共配置,每个应用都要修改,不方便统一管理

分布式配置中心就是为了解决这个问题。

1、原理

分布式配置中心,需要达到以下目的
1:方便的修改配置
2:配置修改后可以热更新,或者通过重启达到目的

先看下流程图
分布式配置中心超轻量的实现方式(带源码)
配置统一存储在数据库中,称为配置中心。各个微服务重启的时候,从配置中心读取配置,如果读到配置,则将配置写入本地的配置文件中。如果读取失败,则从本地配置文件中读取配置后,写入数据库中。这样可以保证在数据库失效的时候,应用本地保存的是上次启动的最新配置,不影响微服务启动。

2、实现方式源码概览

1、配置中心核心源码

public class PropertiesFactory {
    private PropertiesFactory() {
    }

    public static Properties createProperties(String projectName, String propertiesName) {
        if(System.getenv("PN") != null && !"".equals(System.getenv("PN").trim())) {
            projectName = System.getenv("PN");
        }

        return createPropertiesNoEnvPN(projectName, propertiesName);
    }

    public static Properties createPropertiesNoEnvPN(String projectName, String propertiesName) {
        Properties properties = new Properties();
        List<Map<String, String>> propertiesList = new ArrayList();
        DataSourceModel dataSourceModel = loadConfig("/configcenter_db.properties");
        String rootPath = dataSourceModel.getConfigfilepath();

        try {
            System.out.println("====================================");
            System.out.println(projectName);
            System.out.println("====================================");
            if(System.getenv("CDB") != null && !"".equals(System.getenv("CDB").trim())) {
                dataSourceModel.setIp(System.getenv("CDB"));
            }

            System.out.println("====================================");
            System.out.println(dataSourceModel.getIp());
            System.out.println("====================================");
            propertiesList = loadConfigFromDb(dataSourceModel, projectName, propertiesName);
            System.out.println("====================================");
            System.out.println(((List)propertiesList).size());
            System.out.println("====================================");
        } catch (Exception var10) {
            var10.printStackTrace();
        }

        String saveFile;
        if(propertiesList != null && ((List)propertiesList).size() >= 1) {
            Iterator var11 = ((List)propertiesList).iterator();

            while(true) {
                while(var11.hasNext()) {
                    Map<String, String> resultMap = (Map)var11.next();
                    String key = ((String)resultMap.get("key")).trim();
                    String value = ((String)resultMap.get("value")).trim();
                    if("jdbc.maxActive".equals(key) && SystemTools.isWindows()) {
                        properties.put(key, SystemTools.getDbInitSize());
                    } else if("jdbc.initialSize".equals(key) && SystemTools.isWindows()) {
                        properties.put(key, SystemTools.getDbInitSize());
                    } else if("jdbc.minIdle".equals(key) && SystemTools.isWindows()) {
                        properties.put(key, SystemTools.getDbInitSize());
                    } else {
                        properties.put(key, value);
                    }
                }

                saveFile = getSaveFile(rootPath, projectName, propertiesName);
                saveConfigToFile(saveFile, properties);
                break;
            }
        } else {
            saveFile = getSaveFile(rootPath, projectName, propertiesName);
            properties = getConfigFromFile(saveFile);
            insertConfigToDb(dataSourceModel, properties, projectName, propertiesName);
        }

        Map<String, String> map = System.getenv();
        if(map != null) {
            String jenv = (String)map.get("JENV");
            if(jenv == null || "".equals(jenv)) {
                jenv = "dev";
            }

            properties.put("jenv", jenv);
        }

        return properties;
    }

    public static Connection getConnection(DataSourceModel dataSourceModel) {
        Connection conn = null;

        try {
            Class.forName("org.postgresql.Driver");
            conn = DriverManager.getConnection("jdbc:postgresql://" + dataSourceModel.getIp() + ":" + dataSourceModel.getPort() + "/" + dataSourceModel.getDatabase(), dataSourceModel.getUsername(), dataSourceModel.getPassword());
        } catch (ClassNotFoundException var3) {
            var3.printStackTrace();
        } catch (SQLException var4) {
            var4.printStackTrace();
        }

        return conn;
    }

    private static List<Map<String, String>> loadConfigFromDb(DataSourceModel dataSourceModel, String projectName, String propertiesName) {
        List<Map<String, String>> propertiesList = new ArrayList();
        Connection connection = null;
        Statement statement = null;
        ResultSet resultSet = null;

        try {
            connection = getConnection(dataSourceModel);
            if(connection != null) {
                statement = connection.createStatement();
                resultSet = statement.executeQuery("select * from  config_center where projectname = '" + projectName + "' and propertiesname = '" + propertiesName + "'");
                if(resultSet != null) {
                    while(resultSet.next()) {
                        Map<String, String> map = new IdentityHashMap();
                        map.put("projectname", resultSet.getString("projectname"));
                        map.put("propertiesname", resultSet.getString("propertiesname"));
                        map.put("key", resultSet.getString("key").trim());
                        map.put("value", resultSet.getString("value").trim());
                        propertiesList.add(map);
                    }
                }
            }
        } catch (Exception var16) {
            var16.printStackTrace();
        } finally {
            try {
                if(resultSet != null) {
                    resultSet.close();
                }

                if(statement != null) {
                    statement.close();
                }

                if(connection != null) {
                    connection.close();
                }
            } catch (SQLException var15) {
                var15.printStackTrace();
            }

        }

        return propertiesList;
    }

    private static void insertConfigToDb(DataSourceModel dataSourceModel, Properties properties, String projectName, String propertiesName) {
        Connection connection = null;
        Statement statement = null;
        ResultSet resultSet = null;

        try {
            connection = getConnection(dataSourceModel);
            if(connection != null) {
                statement = connection.createStatement();
                Set<Object> keys = properties.keySet();
                Iterator var8 = keys.iterator();

                while(true) {
                    Object key;
                    do {
                        if(!var8.hasNext()) {
                            return;
                        }

                        key = var8.next();
                        String qrySql = "select * from  config_center where projectname = '" + projectName + "' and propertiesname = '" + propertiesName + "' and key='" + key + "'";
                        resultSet = statement.executeQuery(qrySql);
                    } while(resultSet != null && resultSet.next());

                    String insertSql = "insert into config_center values ('" + projectName + "','" + propertiesName + "','" + key + "','" + properties.get(key) + "')";
                    statement.executeUpdate(insertSql);
                }
            }
        } catch (Exception var20) {
            var20.printStackTrace();
        } finally {
            try {
                if(resultSet != null) {
                    resultSet.close();
                }

                if(statement != null) {
                    statement.close();
                }

                if(connection != null) {
                    connection.close();
                }
            } catch (SQLException var19) {
                var19.printStackTrace();
            }

        }

    }

    private static DataSourceModel loadConfig(String configFile) {
        InputStream input = null;
        String host = "";
        int port = 0;
        String database = "";
        String username = "";
        String password = "";
        String configfilepath = "";

        try {
            input = PropertiesFactory.class.getResourceAsStream(configFile);
            Properties properties = new Properties();
            properties.load(input);
            host = properties.getProperty("host");
            port = Integer.valueOf(properties.getProperty("port")).intValue();
            database = properties.getProperty("database");
            username = properties.getProperty("username");
            password = properties.getProperty("password");
            configfilepath = properties.getProperty("configfilepath");
        } catch (Exception var17) {
            var17.printStackTrace();
        } finally {
            if(input != null) {
                try {
                    input.close();
                } catch (IOException var16) {
                    var16.printStackTrace();
                }
            }

        }

        return new DataSourceModel(host, port, database, username, password, configfilepath);
    }

    private static void saveConfigToFile(String saveFile, Properties properties) {
        ArrayList array = getList(properties);

        try {
            File file = new File(saveFile);
            if(!file.exists()) {
                if(!file.getParentFile().exists()) {
                    file.getParentFile().mkdirs();
                }

                file.createNewFile();
            }

            BufferedWriter bw = new BufferedWriter(new FileWriter(saveFile));
            Iterator var5 = array.iterator();

            while(var5.hasNext()) {
                String s = (String)var5.next();
                bw.write(s);
                bw.newLine();
                bw.flush();
            }

            bw.close();
        } catch (IOException var7) {
            var7.printStackTrace();
        }

    }

    private static Properties getConfigFromFile(String saveFile) {
        Properties properties = new Properties();

        try {
            BufferedReader br = new BufferedReader(new FileReader(saveFile));
            ArrayList<String> array = new ArrayList();
            String line = null;

            while((line = br.readLine()) != null) {
                line = line.trim();
                if(!"".equals(line) && !line.startsWith("#")) {
                    array.add(line);
                }
            }

            br.close();
            properties = getProperties(array);
        } catch (Exception var5) {
            var5.printStackTrace();
        }

        return properties;
    }

    private static String getSaveFile(String rootPath, String projectName, String propertiesName) {
        String[] projectNameArray = projectName.split("/");
        String[] var4 = projectNameArray;
        int var5 = projectNameArray.length;

        for(int var6 = 0; var6 < var5; ++var6) {
            String project = var4[var6];
            if(project != null && !"".equals(project)) {
                rootPath = rootPath + File.separator + project;
            }
        }

        return rootPath + File.separator + propertiesName + ".properties";
    }

    private static ArrayList<String> getList(Properties properties) {
        ArrayList<String> array = new ArrayList();
        Set<Object> keys = properties.keySet();
        Iterator var3 = keys.iterator();

        while(var3.hasNext()) {
            Object key = var3.next();
            array.add(key.toString().trim() + "=" + properties.get(key));
        }

        return array;
    }

    private static Properties getProperties(ArrayList<String> array) {
        Properties properties = new Properties();
        Iterator var2 = array.iterator();

        while(var2.hasNext()) {
            String str = (String)var2.next();
            String[] strArray = str.split("=");
            if(strArray.length >= 2) {
                properties.put(strArray[0].trim(), str.replace(strArray[0] + "=", "").trim());
            }
        }

        return properties;
    }
}

2、应用使用方式

Properties properties = PropertiesFactory.createProperties("supp/node1","dbConfig");

supp/node1是应用名
dbConfig是配置名,对应于dbConfigProperties.

3、数据库结构
分布式配置中心超轻量的实现方式(带源码)

分布式配置中心超轻量的实现方式(带源码)