文件监控性能问题【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在本地都可以复现,在线上出现问题的时候,不要怀疑是偶然情况,预定难以解决的问题的时候,先大致分析下问题所在,找不到问题原因就打日志,缩小问题范围,结合源码进行分析。

最新文章

  1. .Net 分布式云平台基础服务建设说明概要
  2. DDD 领域驱动设计-两个实体的碰撞火花
  3. SQL简单语法
  4. IOS 核心动画之CAKeyframeAnimation - iBaby
  5. DataSanp的控制老大-DSServer
  6. cas与NGINX整合(转)
  7. MongoDB 性能优化五个简单步骤
  8. Spring定时任务,Spring4整合quartz2.2,quartz-scheduler定时任务
  9. webservice未能加载文件或程序集“**.DLL”或它的某一个依赖项。
  10. (转)iOS keychain API及其封装
  11. org/hamcrest/SelfDescribing
  12. ci 的控制器文件夹下开加子文件夹
  13. 更新ORACLE数据时遇到锁死情况的处理
  14. Robot Framework语法学习(一)
  15. nginx-push-stream模块源码学习(三)——发布
  16. python django 实现验证码的功能
  17. php代码在服务器中查看接值
  18. PCA与特征选取
  19. MIP开发教程(二) 使用MIP-CLI工具调试MIP网页
  20. 严重:one or more listeners failed. Full details will be found in the appropriate container log file

热门文章

  1. Salesforce LWC学习(二十八) 复制内容到系统剪贴板(clipboard)
  2. ubuntu 18 安装xgboost GPU版本
  3. Java基础语法吐血整理
  4. PHP留言板制作(MySQL+PHP)
  5. Mysql技术内幕之InnoDB锁探究
  6. Dotnet Core多版本API共存的优雅实现
  7. JavaWeb基础总结:Servlet专题
  8. HttpApplication执行顺序
  9. Error:(12, 24) 警告: [deprecation] android.hardware中的Camera已过时.android
  10. java中邮件通知