XxlConf读取配置文件流程

本文探讨了在项目启动时,XxlConfFactory遇到的配置文件读取问题,重点在于XxlConfLocalCacheConf的初始化过程,包括从镜像和远程仓库获取配置,以及监听和定时刷新配置。解决电脑死机导致的配置加载失败关键在于理解这些模块的工作原理。
摘要由CSDN通过智能技术生成

最近由于电脑死机,导致项目重启时一直失败,后来发现是从Xxl配置中心读取配置文件时出错了。顺便看了看项目启动时如何读取配置文件的,话不多说,直接上图。

1.首先在客户端要引入 XxlConfFactory 进行信息配置

一.初始化XxlConfFactory的init()方法

当 XxlConfFactory 被实例化时,会执行到 afterPropertiesSet 方法

Let me see see init() 方法里面有什么

又有三个 init() 方法和一个监听

① XxlConfRemoteConf.init(adminAddress, env, accessToken);

可以看到,仅仅是组装了下数据。

② XxlConfMirrorConf.init(mirrorfile);

可以看到给静态参数赋上了值,没有会抛异常

③  XxlConfLocalCacheConf.init();

public class XxlConfLocalCacheConf {
    private static Logger logger = LoggerFactory.getLogger(XxlConfClient.class);
    private static ConcurrentHashMap<String, XxlConfLocalCacheConf.CacheNode> 
    localCacheRepository = null;
    private static Thread refreshThread;
    private static boolean refreshThreadStop = false;

    public XxlConfLocalCacheConf() {
    }

    public static void init() {
        localCacheRepository = new ConcurrentHashMap();
        Map<String, String> preConfData = new HashMap();
        Map<String, String> mirrorConfData = XxlConfMirrorConf.readConfMirror();
        Map<String, String> remoteConfData = null;
        if (mirrorConfData != null && mirrorConfData.size() > 0) {
            remoteConfData = XxlConfRemoteConf.find(mirrorConfData.keySet());
        }

        if (mirrorConfData != null && mirrorConfData.size() > 0) {
            preConfData.putAll(mirrorConfData);
        }

        if (remoteConfData != null && remoteConfData.size() > 0) {
            preConfData.putAll(remoteConfData);
        }

        if (preConfData != null && preConfData.size() > 0) {
            Iterator var3 = preConfData.keySet().iterator();

            while(var3.hasNext()) {
                String preKey = (String)var3.next();
                set(preKey, (String)preConfData.get(preKey), XxlConfLocalCacheConf.SET_TYPE.PRELOAD);
            }
        }

        // 定时刷新从远程拉取配置文件
        refreshThread = new Thread(new Runnable() {
            public void run() {
                while(!XxlConfLocalCacheConf.refreshThreadStop) {
                    try {
                        XxlConfLocalCacheConf.refreshCacheAndMirror();
                    } catch (Exception var2) {
                        if (!XxlConfLocalCacheConf.refreshThreadStop && !(var2 instanceof InterruptedException)) {
                            XxlConfLocalCacheConf.logger.error(">>>>>>>>>> xxl-conf, refresh thread error.");
                            XxlConfLocalCacheConf.logger.error(var2.getMessage(), var2);
                        }
                    }
                }

                XxlConfLocalCacheConf.logger.info(">>>>>>>>>> xxl-conf, refresh thread stoped.");
            }
        });
        refreshThread.setDaemon(true);
        refreshThread.start();
        logger.info(">>>>>>>>>> xxl-conf, XxlConfLocalCacheConf init success.");
    }

    public static void destroy() {
        ...

    }

    private static void refreshCacheAndMirror() throws InterruptedException {
        if (localCacheRepository.size() == 0) {
            TimeUnit.SECONDS.sleep(3L);
        } else {
            boolean monitorRet = XxlConfRemoteConf.monitor(localCacheRepository.keySet());
            if (!monitorRet) {
                TimeUnit.SECONDS.sleep(10L);
            }

            Set<String> keySet = localCacheRepository.keySet();
            Iterator var3;
            String remoteKey;
            if (keySet.size() > 0) {
                Map<String, String> remoteDataMap = XxlConfRemoteConf.find(keySet);
                if (remoteDataMap != null && remoteDataMap.size() > 0) {
                    var3 = remoteDataMap.keySet().iterator();

                    label43:
                    while(true) {
                        while(true) {
                            if (!var3.hasNext()) {
                                break label43;
                            }

                            remoteKey = (String)var3.next();
                            String remoteData = (String)remoteDataMap.get(remoteKey);
                            XxlConfLocalCacheConf.CacheNode existNode = (XxlConfLocalCacheConf.CacheNode)localCacheRepository.get(remoteKey);
                            if (existNode != null && existNode.getValue() != null && existNode.getValue().equals(remoteData)) {
                                logger.debug(">>>>>>>>>> xxl-conf: RELOAD unchange-pass [{}].", remoteKey);
                            } else {
                                set(remoteKey, remoteData, XxlConfLocalCacheConf.SET_TYPE.RELOAD);
                            }
                        }
                    }
                }
            }

            Map<String, String> mirrorConfData = new HashMap();
            var3 = keySet.iterator();

            while(var3.hasNext()) {
                remoteKey = (String)var3.next();
                XxlConfLocalCacheConf.CacheNode existNode = (XxlConfLocalCacheConf.CacheNode)localCacheRepository.get(remoteKey);
                mirrorConfData.put(remoteKey, existNode.getValue() != null ? existNode.getValue() : "");
            }

            XxlConfMirrorConf.writeConfMirror(mirrorConfData);
            logger.debug(">>>>>>>>>> xxl-conf, refreshCacheAndMirror success.");
        }
    }

    private static void set(String key, String value, XxlConfLocalCacheConf.SET_TYPE optType) {
        ...

    }

    private static XxlConfLocalCacheConf.CacheNode get(String key) {
        ...
    }

    public static String get(String key, String defaultVal) {
        ...
    }

    public static enum SET_TYPE {
        SET,
        RELOAD,
        PRELOAD;

        private SET_TYPE() {
        }
    }

    public static class CacheNode implements Serializable {
        private static final long serialVersionUID = 42L;
        private String value;

        public CacheNode() {
        }

        public CacheNode(String value) {
            this.value = value;
        }

        public String getValue() {
            return this.value;
        }

        public void setValue(String value) {
            this.value = value;
        }
    }
}

可以看到里面有个获取镜像配置数据的方法  XxlConfMirrorConf.readConfMirror();用来获取配置信息,之后将获取的数据放到静态参数。而去还有个线程 refreshThread 该线程的目的就是获取远程仓库的配置文件。

public static boolean monitor(Set<String> keys) {
        Iterator var1 = adminAddressArr.iterator();
        if (var1.hasNext()) {
            String adminAddressUrl = (String)var1.next();
            String url = adminAddressUrl + "/conf/monitor";
            XxlConfParamVO paramVO = new XxlConfParamVO();
            paramVO.setAccessToken(accessToken);
            paramVO.setEnv(env);
            paramVO.setKeys(new ArrayList(keys));
            String paramsJson = BasicJson.toJson(paramVO);
            Map<String, Object> respObj = getAndValid(url, paramsJson, 60);
            return respObj != null;
        } else {
            return false;
        }
    }

我们再看XxlConfMirrorConf.readConfMirror()方法

public static Map<String, String> readConfMirror() {
        // 加载配置文件
        Properties mirrorProp = PropUtil.loadFileProp(mirrorfile);
        if (mirrorProp != null && mirrorProp.stringPropertyNames() != null && mirrorProp.stringPropertyNames().size() > 0) {
            Map<String, String> mirrorConfData = new HashMap();
            Iterator var2 = mirrorProp.stringPropertyNames().iterator();

            while(var2.hasNext()) {
                String key = (String)var2.next();
                mirrorConfData.put(key, mirrorProp.getProperty(key));
            }

            return mirrorConfData;
        } else {
            return null;
        }
    }


// loadFileProp 方法
public static Properties loadFileProp(String propertyFileName) {
        FileInputStream in = null;

        Properties prop;
        try {
            File file = new File(propertyFileName);
            URL url;
            if (!file.exists()) {
                url = null;
                return url;
            }

            url = (new File(propertyFileName)).toURI().toURL();
            in = new FileInputStream(url.getPath());
            if (in != null) {
                prop = new Properties();
                prop.load(new InputStreamReader(in, "utf-8"));
                Properties var5 = prop;
                return var5;
            }

            prop = null;
        } catch (IOException var17) {
            logger.error(var17.getMessage(), var17);
            return null;
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException var16) {
                    logger.error(var16.getMessage(), var16);
                }
            }

        }

        return prop;
    }

mirrorfile 参数时实例化 XxlConfFactory 时所给的配置信息。读取文件存入Map中并返回。

④ XxlConfListenerFactory.addListener();

public static boolean addListener(String key, XxlConfListener xxlConfListener) {
        if (xxlConfListener == null) {
            return false;
        } else if (key != null && key.trim().length() != 0) {
            try {
                String value = XxlConfClient.get(key);
                xxlConfListener.onChange(key, value);
            } catch (Exception var3) {
                logger.error(var3.getMessage(), var3);
            }

            List<XxlConfListener> listeners = (List)keyListenerRepository.get(key);
            if (listeners == null) {
                listeners = new ArrayList();
                keyListenerRepository.put(key, listeners);
            }

            ((List)listeners).add(xxlConfListener);
            return true;
        } else {
            noKeyConfListener.add(xxlConfListener);
            return true;
        }
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值