前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >文件监听之WatchService浅析

文件监听之WatchService浅析

作者头像
lyb-geek
发布2018-07-26 10:28:39
1.8K0
发布2018-07-26 10:28:39
举报
文章被收录于专栏:Linyb极客之路

简介

WatchService是jdk7之后nio包中的新功能。可以看作是文件监控器,通过操作系统原生文件系统来运行。 针对单点多appkey的情况,可以注册开启多个监控器。 每个监控器可看作是后台线程,通过监控文件发出的信号来实现监控。

应用场景

1、感知系统配置文件的变化,修改配置文件内容即时生效,无需重启服务器 2、监控磁盘中的文件变化

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

动态修改配置即时生效实现方法

1、WatchService 实例化

代码语言:javascript
复制
watchService = FileSystems.getDefault().newWatchService();

2、使用 Path 来指定要监控的目录

代码语言:javascript
复制
String filePath = new ClassPathResource(configName).getFile().getParent();
Path path = Paths.get(filePath);

3、将 Path 注册到 WatchService

使用Path.register() 方法注册要监控指定目录的那些事件(创建、修改、删除)

StandardWatchEventKinds.ENTRYCREATE //创建 StandardWatchEventKinds.ENTRYMODIFY //修改 StandardWatchEventKinds.ENTRY_DELETE //删除

代码语言:javascript
复制
path.register(watchService, StandardWatchEventKinds.ENTRY_MODIFY, StandardWatchEventKinds.ENTRY_CREATE);

4、创建监听配置文件守护线程

使用WatchService监听配置文件所在目录内容的变化,包括修改、删除事件。通过后台线程实现阻塞等待内容变化事件,一旦发现有变更,则重新装载配置文件

核心代码块:

代码语言:javascript
复制
private void pollingMonitor() {
        while (true) {
            try {
                // 尝试获取监控池的变化,如果没有则一直等待
                WatchKey watchKey = watchService.take();
                for (WatchEvent<?> event : watchKey.pollEvents()) {
                    if (PropsUtil.CONFIG_NAME.equals(event.context().toString())) {
                        logger.info("监控到{}发生{}操作,将重新加载", event.context(), event.kind());
                        PropsUtil.getInstance().loadProperties(event.context().toString());
                        break;
                    }
                }
                // 完成一次监控就需要重置监控器一次
                watchKey.reset();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

5、注册关闭钩子,当JVM停止时关闭WatchService。

代码语言:javascript
复制
public class WatcherHookThead implements Runnable {
    private static Logger logger = LoggerFactory.getLogger(WatcherHookThead.class);

    private WatchService watchService;

    public WatcherHookThead(WatchService watchService) {
        super();
        this.watchService = watchService;
    }

    @Override
    public void run() {

        try {
            watchService.close();
            logger.info("watcher close success...");
        } catch (IOException e) {
            logger.error("watcher close fail:" + e.getMessage(), e);
        }
    }

}
代码语言:javascript
复制
public void shutDownWatcher() {
        Thread shutDownThread = new Thread(new WatcherHookThead(watchService));
        shutDownThread.setName("shutDownThread");
        Runtime.getRuntime().addShutdownHook(shutDownThread);
    }

验证动态修改配置是否生效测试

1、测试代码

代码语言:javascript
复制
public void testValueIfChange() {
        while (true) {
            String value = PropsUtil.getInstance().getValue("username");
            try {
                System.out.println(StringUtil.format("value--->{}", value));
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

application.properties

初始内容 username=helloworld

不停服务,将username修改为test,观察控制台打印value的值是否动态生效

代码语言:javascript
复制
value--->helloworld
2018-06-29 14:57:57.132  INFO 11988 --- [  watcherThread] com.demo.watchserver.util.WatcherThread  : 监控到application.properties发生ENTRY_MODIFY操作,将重新加载
value--->test

通过控制台可以说明,value已经动态修改,说明配置文件即时被加载

demo地址

https://github.com/lyb-geek/first-watchserver

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-07-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Linyb极客之路 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 简介
  • 应用场景
  • 动态修改配置即时生效实现方法
  • 验证动态修改配置是否生效测试
    • application.properties
    • demo地址
    相关产品与服务
    微服务引擎 TSE
    微服务引擎(Tencent Cloud Service Engine)提供开箱即用的云上全场景微服务解决方案。支持开源增强的云原生注册配置中心(Zookeeper、Nacos 和 Apollo),北极星网格(腾讯自研并开源的 PolarisMesh)、云原生 API 网关(Kong)以及微服务应用托管的弹性微服务平台。微服务引擎完全兼容开源版本的使用方式,在功能、可用性和可运维性等多个方面进行增强。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档