本篇和大家分享的是一个简易配置中心框架IConfCenter,框架是利用空余时间写的,主要以配置文件+redis存储方式作为数据同步驱动,目前支持的配置文件格式有 .properties 和 .config,后期有时间可能增加 .xml 和 .yml文件的识别。
框架结构简单分为:
confserver - 服务端
confAdmin - 配置中心后台管理
confCenter - 配置中心
confclient - 客户端
每分钟获取配置
订阅配置中心刷新配置
发一张配置中心应用到项目中的手工设计图:
confAdmin - 配置中心后台管理
后台管理主要就是一个简单的操作界面,采用springboot+thymeleaf+jquery搭建,目前主要有两个功能:展示配置文件列表和启用某个配置
展示配置文件列表:其实就是读取本地磁盘目录中的配置文件信息,主要的service代码如下:
复制代码
1 /**
2 * 配置文件列表
3 *
4 * @return
5 */
6 public List getListConf() {
7 File baseFile = new File(confCenterConf.confserver_confs_basepath);
8 File[] files = baseFile.listFiles();
9 List list = Arrays.asList(files).
10 stream().
11 sorted(Comparator.comparing(File::lastModified).reversed()).
12 collect(Collectors.toList());
13 return list;
14 }
复制代码
启用某个配置:主要通过界面按钮触发ajax提交一个启动post请求,后端通过解析指定配置文件内容为Map结构,并永久存储于Redis缓存中(直到下一次配置内容更新),最后通过Redis的发布功能通知给订阅该配置的客户端,让客户端通过api重新获取并更新本地配置。主要的Service代码如下:
复制代码
1 /**
2 * 启用某个配置+通知消费端(订阅channel规则:confs_配置文件名)
3 *
4 * @param confPath
5 * @return
6 */
7 public MoRp qyConf(String confPath) {
8 MoRp rp = new MoRp();
9 rp.setStatus(EnumHelper.EmRpStatus.失败.getVal());
10
11 try {
12 //读取配置文件
13 Map map = LoadConf.readConfToMap(confPath);
14 if (map.isEmpty()) {
15 rp.setMessage("加载配置文件失败,稍后重试");
16 return rp;
17 }
18
19 //文件名称
20 String filePathToName = LoadConf.getFilePathToName(confPath, true);
21
22 //缓存key
23 String cacheKey = String.format("confs_%s", filePathToName);
24
25 //2018.09.13 临时增加配置文件修改时间
26 File file = new File(confPath);
27 MoGetConfRp confRp = new MoGetConfRp();
28 confRp.setConfLastModified(file.lastModified());
29 confRp.setConfs(map);
30 confRp.setConfVersion(filePathToName);
31 confRp.setStatus(EnumHelper.EmRpStatus.成功.getVal());
32
33 //存储到缓存中 永久
34 if (jedisTool.set(cacheKey, confRp, 0)) {
35
36 //发布消息,通知客户端更新配置
37 jedisTool.publish(cacheKey, confRp.getConfVersion());
38 rp.setStatus(EnumHelper.EmRpStatus.成功.getVal());
39 rp.setMessage(EnumHelper.EmRpStatus.成功.toString());
40 }
41 } catch (IOException e) {
42 e.printStackTrace();
43 }
44 return rp;
45 }
复制代码
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,然后通过版本号对比是否有更新,如果对比有新版本那么即可更新缓存于本地的配置信息。主要代码如:
复制代码
1 /**
2 * 每分钟获取配置,版本号不一致更新本地缓存
3 *
4 */
5 @Scheduled(initialDelay = 1000 * 60,fixedDelay = 1000 * 60)
6 public void refreshConf() {
7 System.out.println(new Date() + ":当前配置版本" +
8 confCenterConf.confserver_confs_currentConfVersion);
9 if (confCenterConf.confserver_confs_currentConfVersion.isEmpty()) {
10 System.out.println("版本为空,无法自动拉取配置");
11 return;
12 }
13 updateConf(confCenterConf.confserver_confs_currentConfVersion);
14 }
15
16 /**
17 * 更新本地配置
18 * @param strVersion
19 */
20 private void updateConf(String strVersion) {
21 //获取配置中心配置
22 MoGetConfRp rp = confCenterClientService.getConfCenterConf(strVersion);
23 if (rp.getStatus() != EnumHelper.EmRpStatus.成功.getVal()) {
24 return;
25 }else if(rp.getConfLastModified() == confCenterClientService.getConfLastModified()){
26 return;
27 }
28 System.out.println(new Date() + ":更新本地配置");
29 //版本不一致,更新本地缓存
30 confCenterClientService.setConf(rp);
31 }
复制代码
订阅配置中心刷新配置
通过实现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
git地址: https://github.com/shenniubuxing3 云栖社区博客:https://yq.aliyun.com/u/shenniu003https://www.cnblogs.com/wangrudong003/p/9668798.html