本篇和大家分享的是一个简易配置中心框架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, )) { //发布消息,通知客户端更新配置
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() >= ) {
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 = * ,fixedDelay = * )
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

配置中心框架IConfCenter的更多相关文章

  1. 玩转Spring Cloud之配置中心(config server &config client)

     本文内容导航: 一.搭建配置服务中心(config server) 1.1.git方式 1.2.svn方式 1.3.本地文件方式 1.4.解决配置中包含中文内容返回乱码问题 二.搭建配置消费客户端( ...

  2. 分布式配置中心 携程(apollo)

    1.传统配置文件与分布式配置文件区别 传统配置文件:如果修改了配置文件,需要重新打包发布,重新发布服务,而且每个环境的变更配置文件,比较繁琐. 分布式配置文件:将配置文件注册到配置中心上去,可以使用分 ...

  3. SrpingCloud 之SrpingCloud config分布式配置中心

    Config架构 当一个系统中的配置文件发生改变的时候,我们需要重新启动该服务,才能使得新的配置文件生效,spring cloud config可以实现微服务中的所有系统的配置文件的统一管理,而且还可 ...

  4. 【Distributed】分布式配置中心

    一.概述 1.1 什么是分布式配置中心 常用分布式配置中心框架 二.Apollo阿波罗 2.1 Apollo特点 2.2 Apollo整体架构原理 2.3 Apollo Portol 环境搭建 Lin ...

  5. 分布式配置中心Apollo

    1,什么是分布式配置中心 项目中配置文件比较繁杂,而且不同环境的不同配置修改相对频繁,每次发布都需要对应修改配置,如果配置出现错误,需要重新打包发布,时间成本较高,因此需要做统一的分布式注册中心,能做 ...

  6. Apollo配置中心的实战

    31.携程 Apollo 配置中心介绍~1.mp4 32.Apollo核心概念~1.mp4 32.Apollo核心概念~1.mp4 每个应用需要有一个唯一的AppID 要在指定的机器上的server. ...

  7. .Net Core with 微服务 - Consul 配置中心

    上一次我们介绍了Elastic APM组件.这一次我们继续介绍微服务相关组件配置中心的使用方法.本来打算介绍下携程开源的重型配置中心框架 apollo 但是体系实在是太过于庞大,还是让我爱不起来.因为 ...

  8. go微服务框架kratos学习笔记五(kratos 配置中心 paladin config sdk [断剑重铸之日,骑士归来之时])

    目录 go微服务框架kratos学习笔记五(kratos 配置中心 paladin config sdk [断剑重铸之日,骑士归来之时]) 静态配置 flag注入 在线热加载配置 远程配置中心 go微 ...

  9. java框架之SpringCloud(7)-Config分布式配置中心

    前言 分布式系统面临的配置问题 微服务意味着要将单体应用中的业务拆分成一个个子服务,每个服务的粒度相对较小,因此系统中标会出现大量的服务.由于每个服务都需要必要的配置信息才能运行,所以一套集中式的.动 ...

随机推荐

  1. MassTransit 实现发布/订阅

    MassTransit 介绍  先看下masstransit 官网介绍:MassTransit 是一个自由.开源.轻量级的消息总线, 用于使用. NET 框架创建分布式应用程序.MassTransit ...

  2. 嘿嘿嘿,开始自学mysql

    开始学习mysql了,作为非计算机专业学生,必须需要一个地方来给自己的知识进行一些记录和总结. 一SQL语句 数据库是不认识java语言的,但是我们同样要与数据库交互,这时需要使用到数据库认识的语言S ...

  3. selenium+java破解极验滑动验证码的示例代码

    转自: https://www.jianshu.com/p/1466f1ba3275 selenium+java破解极验滑动验证码 卧颜沉默 关注 2017.08.15 20:07* 字数 3085  ...

  4. dummy_backend_queue.go

    ) } func (d *dummyBackendQueue) Empty() error {     return nil }

  5. 根据http协议下载文件保存到相应的文件下

    本实例通过提供的http网址来下载文件,并保存到本地指定的文件下. 本例提供的网址为:http://112.53.80.131:8888/database/11.mdb,下载的文件名为:11.mdb ...

  6. 【强连通分量】Bzoj1051 HAOI2006 受欢迎的牛

    Description 每一头牛的愿望就是变成一头最受欢迎的牛.现在有N头牛,给你M对整数(A,B),表示牛A认为牛B受欢迎. 这种关系是具有传递性的,如果A认为B受欢迎,B认为C受欢迎,那么牛A也认 ...

  7. [Noi2016]区间 BZOJ4653 洛谷P1712 Loj#2086

    额... 首先,看到这道题,第一想法就是二分答案+线段树... 兴高采烈的认为我一定能AC,之后发现n是500000... nlog^2=80%,亲测可过... 由于答案是求满足题意的最大长度-最小长 ...

  8. MIP 问题解决方案大全(2018-06更新)

    在 MIP 推出后,我们收到了一些站长的疑问.现将常见问题整理出来,帮助大家了解 MIP 的知识. 一.MIP 认知类问题 二.改造前准备 三.前端改造,组件使用 四.提交生效 五.MIPCache ...

  9. 工厂模式讲解, 引入Spring IOC

    目录 引入 简单工厂 抽象工厂 Spring的bean工厂 模拟Spring工厂实现 模拟IOC 引入 假设有一个司机, 需要到某个城市, 于是我们给他一辆汽车 public class Demo { ...

  10. 实用抓包工具:whistle

    无论是前端开发还是客户端,实际开发过程中,抓包都经常被用到.工欲善其事必先利其器,一款好用的抓包工具也是必须的. 说到抓包,Windows系统上不少人都用过Fiddler,Mac或Linux上用Cha ...