• flume spooldir bug修复


    BUG:在往目录中copy大文件时,没有复制完,flume就开始读-->导致报错

    在代码中体现为:
    org.apache.flume.client.avro.ReliableSpoolingFileEventReader.retireCurrentFile()方法内

    解决方案:
    等文件完全拷贝完成,再开始读这个文件

    1.5版本:

    private Optional<FileInfo> getNextFile() {
     7   /* Filter to exclude finished or hidden files */
     8   FileFilter filter = new FileFilter() {
     9     public boolean accept(File candidate) {
    10       String fileName = candidate.getName();
    11       if ((candidate.isDirectory()) ||
    12           (fileName.endsWith(completedSuffix)) ||
    13           (fileName.startsWith(".")) ||
    14           ignorePattern.matcher(fileName).matches()) {
    15         return false;
    16       }
    17       return true;
    18     }
    19   };
    20   List<File> candidateFiles = Arrays.asList(spoolDirectory.listFiles(filter)); //获取spoolDirectory下满足条件的文件
    21   if (candidateFiles.isEmpty()) {
    22     return Optional.absent();
    23   } else {
    24     Collections.sort(candidateFiles, new Comparator<File>() { //按最后修改时间排序文件
    25       public int compare(File a, File b) {
    26         int timeComparison = new Long(a.lastModified()).compareTo(
    27             new Long(b.lastModified()));
    28         if (timeComparison != 0) {
    29           return timeComparison;
    30         }
    31         else {
    32           return a.getName().compareTo(b.getName());
    33         }
    34       }
    35     });
    36     File nextFile = candidateFiles.get(0); //因为每次获取到的文件处理完都会被标记为已完成,所以直接取拍完序的第一个
    37     //修复传输大文件报错文件被修改的BUG
    38     this.checkFileCpIsOver(nextFile);//此处被阻塞,直到文件拷贝文件或者超过20秒
    39  
    40     try {
    41       // roll the meta file, if needed
    42       String nextPath = nextFile.getPath()

    1.7版本 :

      private Optional<FileInfo> getNextFile() {
        List<File> candidateFiles = Collections.emptyList();
    
        if (consumeOrder != ConsumeOrder.RANDOM ||
            candidateFileIter == null ||
            !candidateFileIter.hasNext()) {
          candidateFiles = getCandidateFiles(spoolDirectory.toPath());
          listFilesCount++;
          candidateFileIter = candidateFiles.iterator();
        }
    
        if (!candidateFileIter.hasNext()) { // No matching file in spooling directory.
          return Optional.absent();
        }
    
        File selectedFile = candidateFileIter.next();
        if (consumeOrder == ConsumeOrder.RANDOM) { // Selected file is random.
          return openFile(selectedFile);
        } else if (consumeOrder == ConsumeOrder.YOUNGEST) {
          for (File candidateFile : candidateFiles) {
            long compare = selectedFile.lastModified() -
                candidateFile.lastModified();
            if (compare == 0) { // ts is same pick smallest lexicographically.
              selectedFile = smallerLexicographical(selectedFile, candidateFile);
            } else if (compare < 0) { // candidate is younger (cand-ts > selec-ts)
              selectedFile = candidateFile;
            }
          }
        } else { // default order is OLDEST
          for (File candidateFile : candidateFiles) {
            long compare = selectedFile.lastModified() -
                candidateFile.lastModified();
            if (compare == 0) { // ts is same pick smallest lexicographically.
              selectedFile = smallerLexicographical(selectedFile, candidateFile);
            } else if (compare > 0) { // candidate is older (cand-ts < selec-ts).
              selectedFile = candidateFile;
            }
          }
        }
    
        firstTimeRead = true;
    
      //修复传输大文件报错文件被修改的BUG
        this.checkFileCpIsOver(selectedFile);//此处被阻塞,直到文件拷贝文件或者超过20秒
        return openFile(selectedFile);
      }

    解决代码:

     /**
     *
     * @Title: checkFileCpIsOver
     * @Description: TODO(用来检查文件拷贝是否完成)
     * @param @param currentFile    设定文件
     * @return void    返回类型
     * @throws
     */
    private void checkFileCpIsOver(File file) {
        long modified = file.lastModified();//目前文件的修改时间
        long length = file.length();//目前文件的大小
        try {
          Thread.sleep(1000);//等待1秒钟
        } catch (InterruptedException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
        }
        File currentFile = new File(file.getAbsolutePath());
        int count = 0;//记录循环次数,超过20次,也就是10秒后抛出异常
        while(currentFile.lastModified() != modified || currentFile.length() != length) {
            if(count > 20) {
                String message = "File Copy time too long. please check copy whether exception!" + "
    "
                          + "File at :" + file.getAbsolutePath() + "
    "
                          + "File current length is:" + currentFile.lastModified();
                new IllegalStateException(message);
            }
            count++;
            modified = currentFile.lastModified();
            length = currentFile.length();
            try {
              Thread.sleep(500);//等待500毫秒
            } catch (InterruptedException e) {
              // TODO Auto-generated catch block
              e.printStackTrace();
            }
            currentFile = new File(file.getAbsolutePath());
             
             
        }
        //一直到文件传输完成就可以退出
    }
  • 相关阅读:
    游戏开发中的图像生成
    图像特征提取:图像的矩特征
    图像特征提取:斑点检测
    Android Camera系统深入理解
    阶段1 语言基础+高级_1-3-Java语言高级_04-集合_01 Collection集合_7_增强for循环
    阶段1 语言基础+高级_1-3-Java语言高级_04-集合_01 Collection集合_5_迭代器的代码实现
    阶段1 语言基础+高级_1-3-Java语言高级_04-集合_01 Collection集合_4_Iterator接口介绍
    阶段1 语言基础+高级_1-3-Java语言高级_04-集合_01 Collection集合_3_Collection集合常用功能
    阶段1 语言基础+高级_1-3-Java语言高级_03-常用API第二部分_第6节 基本类型包装类_4_包装类_基本类型与字符串类型之间
    阶段1 语言基础+高级_1-3-Java语言高级_03-常用API第二部分_第6节 基本类型包装类_3_包装类_自动装箱与自动拆箱
  • 原文地址:https://www.cnblogs.com/sprinng/p/6697589.html
Copyright © 2020-2023  润新知