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

配置中心框架IConfCenter

程序员文章站 2022-05-13 22:52:27
本篇和大家分享的是一个简易配置中心框架IConfCenter,框架是利用空余时间写的,主要以配置文件+redis存储方式作为数据同步驱动,目前支持的配置文件格式有 .properties 和 .config,后期有时间可能增加 .xml 和 .yml文件的识别。 框架结构简单分为: confserv ......

本篇和大家分享的是一个简易配置中心框架iconfcenter,框架是利用空余时间写的,主要以配置文件+redis存储方式作为数据同步驱动,目前支持的配置文件格式有 .properties 和 .config,后期有时间可能增加 .xml 和 .yml文件的识别。

框架结构简单分为:

  • confserver - 服务端

    confadmin - 配置中心后台管理

    confcenter - 配置中心

  • confclient - 客户端

    每分钟获取配置

    订阅配置中心刷新配置

发一张配置中心应用到项目中的手工设计图:

配置中心框架IConfCenter

 

confadmin - 配置中心后台管理

后台管理主要就是一个简单的操作界面,采用springboot+thymeleaf+jquery搭建,目前主要有两个功能:展示配置文件列表和启用某个配置

展示配置文件列表:其实就是读取本地磁盘目录中的配置文件信息,主要的service代码如下:

 1     /**
 2      * 配置文件列表
 3      *
 4      * @return
 5      */
 6     public list<file> getlistconf() {
 7         file basefile = new file(confcenterconf.confserver_confs_basepath);
 8         file[] files = basefile.listfiles();
 9         list<file> 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<string, object> 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

配置中心框架IConfCenter