本篇和大家分享的是一个简易配置中心框架 IConfCenter, 框架是利用空余时间写的, 主要以配置文件 + redis 存储方式作为数据同步驱动, 目前支持的配置文件格式有 .properties 和 .config, 后期有时间可能增加 .xml 和 .yml 文件的识别.
框架结构简单分为:
confserver - 服务端
confAdmin - 配置中心后台管理
confCenter - 配置中心
confclient - 客户端
每分钟获取配置
订阅配置中心刷新配置
发一张配置中心应用到项目中的手工设计图:
confAdmin - 配置中心后台管理
后台管理主要就是一个简单的操作界面, 采用 springboot+thymeleaf+jquery 搭建, 目前主要有两个功能: 展示配置文件列表和启用某个配置
展示配置文件列表: 其实就是读取本地磁盘目录中的配置文件信息, 主要的 service 代码如下:
- /**
- * 配置文件列表
- *
- * @return
- */
- public List<File> getListConf() {
- File baseFile = new File(confCenterConf.confserver_confs_basepath);
- File[] files = baseFile.listFiles();
- List<File> list = Arrays.asList(files).
- stream().
- sorted(Comparator.comparing(File::lastModified).reversed()).
- collect(Collectors.toList());
- return list;
- }
启用某个配置: 主要通过界面按钮触发 ajax 提交一个启动 post 请求, 后端通过解析指定配置文件内容为 Map 结构, 并永久存储于 Redis 缓存中 (直到下一次配置内容更新), 最后通过 Redis 的发布功能通知给订阅该配置的客户端, 让客户端通过 api 重新获取并更新本地配置. 主要的 Service 代码如下:
- /**
- * 启用某个配置 + 通知消费端 (订阅 channel 规则: confs_配置文件名)
- *
- * @param confPath
- * @return
- */
- public MoRp qyConf(String confPath) {
- MoRp rp = new MoRp();
- rp.setStatus(EnumHelper.EmRpStatus. 失败. getVal());
- try {
- // 读取配置文件
- Map<String, Object> map = LoadConf.readConfToMap(confPath);
- if (map.isEmpty()) {
- rp.setMessage("加载配置文件失败, 稍后重试");
- return rp;
- }
- // 文件名称
- String filePathToName = LoadConf.getFilePathToName(confPath, true);
- // 缓存 key
- String cacheKey = String.format("confs_%s", filePathToName);
- //2018.09.13 临时增加配置文件修改时间
- File file = new File(confPath);
- MoGetConfRp confRp = new MoGetConfRp();
- confRp.setConfLastModified(file.lastModified());
- confRp.setConfs(map);
- confRp.setConfVersion(filePathToName);
- confRp.setStatus(EnumHelper.EmRpStatus. 成功. getVal());
- // 存储到缓存中 永久
- if (jedisTool.set(cacheKey, confRp, 0)) {
- // 发布消息, 通知客户端更新配置
- jedisTool.publish(cacheKey, confRp.getConfVersion());
- rp.setStatus(EnumHelper.EmRpStatus. 成功. getVal());
- rp.setMessage(EnumHelper.EmRpStatus. 成功. toString());
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- return rp;
- }
confCenter - 配置中心
主要提供了一个获取指定版本的配置文件信息 api, 信息来源由 Redis 缓存提供, 当 Redis 缓存不存在时不会去解析配置文件, 因此主要用 ConfiAdmin 管理后台触发数据来源. 其主要代码:
- /**
- * 获取配置信息
- *
- * @param rq
- * @return
- */
- public MoGetConfRp getconf(MoGetConfRq rq) {
- MoGetConfRp rp = new MoGetConfRp();
- try {
- // 未指定配置版本, 采用默认配置版本
- if (rq.getConfVersion().isEmpty()) {
- rq.setConfVersion(confCenterConf.confserver_confs_currentConfVersion);
- }
- if (rq.getConfVersion().isEmpty()) {
- rp.setMessage("未找到配置版本");
- return rp;
- }
- // 缓存 key
- String cacheKey = String.format("confs_%s", rq.getConfVersion());
- // 获取缓存中是否存在
- rp = jedisTool.get(cacheKey, MoGetConfRp.class);
if (rp.getStatus() == EnumHelper.EmRpStatus. 成功. getVal() &&
- rp.getConfs().size()>= 1) {
- rp.setStatus(EnumHelper.EmRpStatus. 成功. getVal());
- rp.setMessage(EnumHelper.EmRpStatus. 成功. toString());
- return rp;
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- return rp;
- }
confclient - 客户端
主要干了两个事情: 每分钟获取配置和订阅配置中心刷新配置. 该客户端项目各位可以打包成 jar 引入项目中, 加上相关配置即可引入配置中心客户端
每分钟获取配置
为了配置内容的一致性, 这里采用了 Scheduled 每隔一分钟请求一下配置中心 api, 然后通过版本号对比是否有更新, 如果对比有新版本那么即可更新缓存于本地的配置信息. 主要代码如:
- /**
- * 每分钟获取配置, 版本号不一致更新本地缓存
- *
- */
- @Scheduled(initialDelay = 1000 * 60,fixedDelay = 1000 * 60)
- public void refreshConf() {
- System.out.println(new Date() + ": 当前配置版本" +
- confCenterConf.confserver_confs_currentConfVersion);
- if (confCenterConf.confserver_confs_currentConfVersion.isEmpty()) {
- System.out.println("版本为空, 无法自动拉取配置");
- return;
- }
- updateConf(confCenterConf.confserver_confs_currentConfVersion);
- }
- /**
- * 更新本地配置
- * @param strVersion
- */
- private void updateConf(String strVersion) {
- // 获取配置中心配置
- MoGetConfRp rp = confCenterClientService.getConfCenterConf(strVersion);
if (rp.getStatus() != EnumHelper.EmRpStatus. 成功. getVal()) {
- return;
- }else if(rp.getConfLastModified() == confCenterClientService.getConfLastModified()){
- return;
- }
- System.out.println(new Date() + ": 更新本地配置");
- // 版本不一致, 更新本地缓存
- confCenterClientService.setConf(rp);
- }
订阅配置中心刷新配置
通过实现 CommandLineRunner 接口的 run 方法, 在项目启动时通过 Redis 订阅配置中心消息, 达到配置中心主动通知更新配置的目的. 主要代码:
- /**
- * 程序启动执行服务 订阅配置中心刷新配置通道
- *
- * @param strings
- * @throws Exception
- */
- @Override
- public void run(String... strings) throws Exception {
- // 订阅配置中心刷新配置通道
- jedisTool.subscribe(
- "confs_" + confCenterConf.confserver_confs_currentConfVersion,
- b -> {
- System.out.println(new Date() + ": 收到配置中心刷新配置通知, 版本 -" + b);
- updateConf(b.toString());
- });
- }
在文章结尾时, 发一张配置中心后台管理界面图, 并希望各位能够喜欢配置中心框架 IConfCenter
来源: https://www.cnblogs.com/wangrudong003/p/9668798.html