美文网首页扣丁学堂Java培训
扣丁学堂java培训简述Java动态修改配置即时生效的方式Wat

扣丁学堂java培训简述Java动态修改配置即时生效的方式Wat

作者: 994d14631d16 | 来源:发表于2018-06-26 16:57 被阅读1次

 这种方式仅适合于比较小的项目,例如只有一两台服务器,而且配置文件是可以直接修改的。例如Springmvc以war包的形式部署,可以直接修改resources中的配置文件。如果是Springboot项目,还想用这种方式的话,就要引用一个外部可以编辑的文件,比如一个固定的目录,因为springboot大多数以jar包部署,打到包里的配置文件没办法直接修改。如果是比较大的项目,最好还是用配置中心,例如携程的Apollo、Consul等。

原始方式

原始方式指的是每次要修改配置的时候,都要重新打包发布或者重启服务器。

假设我们用springmvc开发,开发完成后打成war包部署到tomcat上,如果这时我们修改一个短信接口地址。

我们要做如下操作:

1、打开配置文件,修改配置信息;

2、编译打包;

3、停止tomcat,删除旧的项目目录;

4、将新的war包放到webapps,启动tomcat。

当然,可以直接在tomcat中找到这个项目的配置文件,然后修改,但同样需要重启tomcat。

如果只是单纯做开发或者测试,除了有点浪费时间外,当然可以接受。那么,既不想浪费时间又不想重启tomcat呢,有没有办法呢。这就轮到本文介绍的这种方式了。

WatchService方式

Java提供了WatchService接口,这个接口是利用操作系统本身的文件监控器对目录和文件进行监控,当被监控对象发生变化时,会有信号通知,从而可以高效的发现变化。

这种方式大致的原理:先根据操作系统new一个监控器(WatchService),然后选择要监控的配置文件所在目录或文件,然后订阅要监控的事件,例如创建、删除、编辑,最后向被监控位置注册这个监控器。一旦触发对应我们所订阅的事件时,执行相应的逻辑即可。

先上代码吧,这是在一个springmvc项目里,监控的是resources目录。

@Repository

public class ConfigWatcher {

  private static final Logger logger = LoggerFactory.getLogger(ConfigWatcher.class);

  private static WatchService watchService;

  @PostConstruct

  public void init() {

    logger.info("启动配置文件监控器");

    try {

      watchService = FileSystems.getDefault().newWatchService();

      URL url = ConfigWatcher.class.getResource("/");

      Path path = Paths.get(url.toURI());

      path.register(watchService, StandardWatchEventKinds.ENTRY_MODIFY, StandardWatchEventKinds.ENTRY_CREATE);

    } catch (Exception e1) {

      e1.printStackTrace();

    }

    /**

    * 启动监控线程

    */

    Thread watchThread = new Thread(new WatchThread());

    watchThread.setDaemon(true);

    watchThread.start();

    /**注册关闭钩子*/

    Thread hook = new Thread(new Runnable() {

      @Override

      public void run() {

        try {

          watchService.close();

        } catch (IOException e) {

          e.printStackTrace();

        }

      }

    });

    Runtime.getRuntime().addShutdownHook(hook);

  }

  public class WatchThread implements Runnable {

    @Override

    public void run() {

      while (true) {

        try {

          // 尝试获取监控池的变化,如果没有则一直等待

          WatchKey watchKey = watchService.take();

          for (WatchEvent event : watchKey.pollEvents()) {

            String editFileName = event.context().toString();

            logger.info(editFileName);

            /**

            * 重新加载配置

            */

          }

          watchKey.reset();//完成一次监控就需要重置监控器一次

        } catch (Exception e) {

          e.printStackTrace();

        }

      }

    }

  }

}

代码非常简单,一看就懂,在项目启动的时候,用FileSystems.getDefault().newWatchService()创建一个WatchService,这是根据操作系统来的。然后获取resources目录的URL,并由此获取Path,然后调用Path对象的register方法,注册监控器,订阅了编辑和创建事件。事件在StandardWatchEventKinds类中定义,共有四种:

1、StandardWatchEventKinds#OVERFLOW

2、StandardWatchEventKinds#ENTRY_CREATE

3、StandardWatchEventKinds#ENTRY_DELETE

4、StandardWatchEventKinds#ENTRY_MODIFY

然后单独启动了一个WatchThread线程来处理变化逻辑,在一个while无限循环中调用take()方法,直到有变化发生,一旦是我们监控的配置文件发生了变化,则调用我们的逻辑重新加载配置。另外,每次有变化发生后,要调用watchKey.reset()方法来重置监控器。

最后,还要注册一个hook,在jvm关闭的时候可以关闭监控器。

有了这种方式,当我们有一些配置变化的时候,就可以直接到tomcat下修改配置文件,不用重启就可以生效了。

本文主要介绍的是这种方式,上面也说了,这种方式只适合非常简单的项目,对于大型项目,就需要用到更高级的方式了。

配置中心的方式

当项目复杂度变高,配置修改后实时生效,灰度发布,分环境、分集群管理配置,完善的权限、审核机制可能都变成项目中要考虑的问题,这个时候,单纯依赖配置文件就显得力不从心了。

目前比较用的比较多的配置中心有etcd、zookeeper、disconf、Apollo等。disconf、Apollo都是属于拿来即用的,功能完善,而且有配套的UI。而etcd和zookeeper需要一些定制开发。

以上就是Java动态修改配置即时生效的方式WatchService的方式各位同学可以根据需要自行选择,更详细的内容请登录扣丁学堂官网,或关注微信公众号进行了解,更有大量java在线视频教程等你来观看!

相关文章

网友评论

    本文标题:扣丁学堂java培训简述Java动态修改配置即时生效的方式Wat

    本文链接:https://www.haomeiwen.com/subject/opymyftx.html