• 配置中心框架IConfCenter


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

    框架结构简单分为:

    • confserver - 服务端

      confAdmin - 配置中心后台管理

      confCenter - 配置中心

    • confclient - 客户端

      每分钟获取配置

      订阅配置中心刷新配置

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

    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

     

  • 相关阅读:
    Intellij IDEA 关闭阿里编码规约“请不要使用行尾注释”提醒
    VS 进行了无法编译的编辑
    IntelliJ IDEA lombok log 报红
    SQL Server 事务执行SQL
    Linux 检查应用不在现就重启
    Java入门5.2---String类、StringBuffer类、StringBuilder类、System类、Data类、SimpleDataFormat类、Calendar类、Math类、BigInteger类与BigDecimal类
    为什么要进行补偿
    解决flex布局中 space-between方法的排版问题
    桑基图的使用场景
    清蒸罗非鱼的做法和步骤
  • 原文地址:https://www.cnblogs.com/wangrudong003/p/9668798.html
Copyright © 2020-2023  润新知