• 欢迎访问开心洋葱网站,在线教程,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站,欢迎加入开心洋葱 QQ群
  • 为方便开心洋葱网用户,开心洋葱官网已经开启复制功能!
  • 欢迎访问开心洋葱网站,手机也能访问哦~欢迎加入开心洋葱多维思维学习平台 QQ群
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏开心洋葱吧~~~~~~~~~~~~~!
  • 由于近期流量激增,小站的ECS没能经的起亲们的访问,本站依然没有盈利,如果各位看如果觉着文字不错,还请看官给小站打个赏~~~~~~~~~~~~~!

文件监控性能问题【BUG】

JAVA相关 喜中5000万 1369次浏览 0个评论

文件监控性能问题【BUG】

背景:JAVA写了一个文件夹目录监控的程序,使用的是org.apache.commons.io.monitor 包,项目稳定运行了一个月,现场反馈,文件夹数据处理越来越慢,等到数据推送到前端要好几分钟,于是开始了寻找问题的路程。

监控代码

之前写的文件监控代码

问题发现

我在ApplicationRunner的实现类中重写了run方法,打印了日志

    @Override
    public void run(ApplicationArguments applicationArguments) throws Exception {
        log.info("监听开始");
        // 轮询间隔 1 秒
        long interval = TimeUnit.SECONDS.toMillis(1);
        // 创建过滤器
        IOFileFilter directories = FileFilterUtils.and(
                FileFilterUtils.directoryFileFilter(),
                HiddenFileFilter.VISIBLE);
        IOFileFilter files = FileFilterUtils.and(
                FileFilterUtils.fileFileFilter(),
                FileFilterUtils.suffixFileFilter(fileEnd));
        IOFileFilter filter = FileFilterUtils.or(directories, files);
        // 使用过滤器
        FileAlterationObserver observer = new FileAlterationObserver(new File(baseDataSyncDir), filter);
        observer.addListener(new FileMonitor());
        //创建文件变化监听器
        FileAlterationMonitor monitor = new FileAlterationMonitor(interval, observer);
        // 开始监控
        monitor.start();
        log.info("监听开始{}",baseDataSyncDir);
    }	

本地调试,秒打印两行日志,但是放到现场运行,这两行日志相差三分钟,在之后的fileCreate 监听中也是发现大概三分钟才能发现一批新数据,这就是导致数据推送不及时的原因。

在发现问题过后,我仔细想了下文件监控的原理,到底是怎么来监控文件的呢,找了下源码看了下,果然,是循环处理所有文件。FileAlterationObserver中的checkeNotify()方法,就是获取所有的文件,然后进行一个个的判断。

 public void checkAndNotify() {
        Iterator var1 = this.listeners.iterator();

        while(var1.hasNext()) {
            FileAlterationListener listener = (FileAlterationListener)var1.next();
            listener.onStart(this);
        }

        File rootFile = this.rootEntry.getFile();
        if (rootFile.exists()) {
            this.checkAndNotify(this.rootEntry, this.rootEntry.getChildren(), this.listFiles(rootFile));
        } else if (this.rootEntry.isExists()) {
            this.checkAndNotify(this.rootEntry, this.rootEntry.getChildren(), FileUtils.EMPTY_FILE_ARRAY);
        }

        Iterator var5 = this.listeners.iterator();

        while(var5.hasNext()) {
            FileAlterationListener listener = (FileAlterationListener)var5.next();
            listener.onStop(this);
        }

    }

分析问题

问题出现的原因:由于程序在处理了文件之后,并没有将文件进行删除处理,而是将数据移动到当前目录的子目录中,但是子目录依旧在程序监控的根目录下,这就导致根目录下的数据量越来越大,进而引发了项目文件监控处理一次需要三分钟,也就是说会随着文件数据量的逐渐增加,处理一次需要的时间也会逐渐增加,最终会导致程序崩溃。

解决方案

1.在处理完文件之后,将文件删除。

2.处理完文件之后,将文件移动到不在监控文件夹下

BUG感悟

不是所有的bug在本地都可以复现,在线上出现问题的时候,不要怀疑是偶然情况,预定难以解决的问题的时候,先大致分析下问题所在,找不到问题原因就打日志,缩小问题范围,结合源码进行分析。


开心洋葱 , 版权所有丨如未注明 , 均为原创丨未经授权请勿修改 , 转载请注明文件监控性能问题【BUG】
喜欢 (0)

您必须 登录 才能发表评论!

加载中……