文件监控性能问题【BUG】

Electron小白入门自学笔记(一)

文件监控性能问题【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 监听中也是发现大概三分钟才能发现一批新数据,这就是导致数据推送不及时的原因。

C/C++内存对齐详解

在发现问题过后,我仔细想了下文件监控的原理,到底是怎么来监控文件的呢,找了下源码看了下,果然,是循环处理所有文件。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在本地都可以复现,在线上出现问题的时候,不要怀疑是偶然情况,预定难以解决的问题的时候,先大致分析下问题所在,找不到问题原因就打日志,缩小问题范围,结合源码进行分析。

Java反射全解析(使用、原理、问题、在Android中的应用)

给TA买糖
共{{data.count}}人
人已赞赏
经验教程

Java反射全解析(使用、原理、问题、在Android中的应用)

2021-1-19 11:29:00

经验教程

Electron小白入门自学笔记(一)

2021-1-19 12:03:00

⚠️
免责声明:根据《计算机软件保护条例》第十七条规定“为了学习和研究软件内含的设计思想和原理,通过安装、显示、传输或者存储软件等方式使用软件的,可以不经软件著作权人许可,不向其支付报酬。”您需知晓本站所有内容资源均来源于网络,仅供用户交流学习与研究使用,版权归属原版权方所有,版权争议与本站无关,用户本人下载后不能用作商业或非法用途,需在24个小时之内从您的电脑中彻底删除上述内容,否则后果均由用户承担责任;如果您访问和下载此文件,表示您同意只将此文件用于参考、学习而非其他用途,否则一切后果请您自行承担,如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。 本站为个人博客非盈利性站点,所有软件信息均来自网络,所有资源仅供学习参考研究目的,并不贩卖软件,不存在任何商业目的及用途,网站会员捐赠是您喜欢本站而产生的赞助支持行为,仅为维持服务器的开支与维护,全凭自愿无任何强求。本站部份代码及教程来源于互联网,仅供网友学习交流,若您喜欢本文可附上原文链接随意转载。
无意侵害您的权益,请发送邮件至 momeis6@qq.com 或点击右侧 私信:momeis 反馈,我们将尽快处理。
0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
今日签到
有新私信 私信列表
搜索