如何在 Camel 中引入延迟以防止在复制文件之前锁定文件?

How do I introduce a Delay in Camel to prevent file locking before the files are copied in?

我正在使用 Camel、ActiveMq 和 JMS 轮询目录并处理它找到的任何文件。较大文件的问题是它们在被完全复制到目录之前就开始处理。我已经假设(是的,我知道你的假设是什么)文件系统会阻止它——但这似乎不是真的。 Camel 文档中的示例似乎不起作用。这是我在 RouteBuilder 的配置方法中的代码:

    from("file://" + env.getProperty("integration.directory.scan.add.eng.jobslist")+"?consumer.initialDelay=100000")
        .doTry()
            .setProperty("servicePath").constant("/job")
            .setProperty("serviceMethod").constant("POST")
            .process("engImportJobsFromFileProcessor")
        .doCatch(Exception.class)
            .to("log:-- Add Job(s) Error -------------------------")
            .choice()
                .when(constant(env.getProperty("eng.mail.enabled.flag.add.jobslist.yn")).isEqualToIgnoreCase("Y"))
                    .setHeader("subject", constant(env.getProperty("integration.mq.topic.add.eng.jobslist.error.email.subject")))
                    .to("direct://email.eng")
                .otherwise()
                    .to("log:-----------------------------------------")
                    .to("log:-- Email for JOBSLIST IS DISABLED")
                    .to("log:-----------------------------------------")
            .end()
        .end()
        .log("Finished loading jobs from file ")
    ;

如您所见,我尝试设置 'initialDelay',我也尝试了 'delay' 和 'readLock=changed',但没有任何区别。一旦文件到达目录,Camel 就会开始处理。我所追求的只是在轮询文件之前的一个很好的简单延迟。有什么想法吗?

使用选项 readLockMinAge

来自File2 component documentation

This option allows you to specify a minimum age a file must be before attempting to acquire the read lock. For example, use readLockMinAge=300s to require that the file is at least 5 minutes old.

对于 100 秒的延迟,URI 可能如下所示:

from("file://" + env.getProperty("integration.directory.scan.add.eng.jobslist")+"?readLock=changed&readLockMinAge=100s")

使用选项 "readLock=changed" 、 "readLockCheckInterval=1000" 和 readLockMinAge=20s 的组合 (1000 以毫秒为单位,默认值,应该更改为更高的值,因为写入速度较慢,即文件大小在很长一段时间后发生变化,这可能发生在某些文件系统上,文件大小在传输过程中变化不是很频繁)

文件组件文档@http://camel.apache.org/file2.html

for readlock=changed

changed is using file length/modification timestamp to detect whether the file is currently being copied or not. Will at least use 1 sec. to determine this, so this option cannot consume files as fast as the others, but can be more reliable as the JDK IO API cannot always determine whether a file is currently being used by another process. The option readLockCheckInterval can be used to set the check frequency.

for readLockCheckInterval=1000

Camel 2.6: Interval in milliseconds for the read-lock, if supported by the read lock. This interval is used for sleeping between attempts to acquire the read lock. For example when using the changed read lock, you can set a higher interval period to cater for slow writes. The default of 1 sec. may be too fast if the producer is very slow writing the file.

for readLockMinAge=20s

Camel 2.15: This option applies only to readLock=change. This option allows you to specify a minimum age a file must be before attempting to acquire the read lock. For example, use readLockMinAge=300s to require that the file is at least 5 minutes old. This can speedup the poll when the file is old enough as it will acquire the read lock immediately.

所以最后你的端点应该看起来像

from("file://" + env.getProperty("integration.directory.scan.add.eng.jobslist")+"?consumer.initialDelay=100000&readLock=changed&readLockCheckInterval=1000&readLockMinAge=20s")

OK,原来是东西组合。首先,出于多种原因,我在 IntelliJ 内部和外部进行了测试——一个是在 IDEA 中使用电子邮件的安全问题。 Tomcat,在 IntelliJ 之外正在选择 webapps/ROOT 目录中的一个 类 文件夹,它覆盖了我对 uri 选项的更改。这就是让我发疯的原因。由于几个月前的部署错误,该 ROOT 文件夹一直存在。但即使我使用相同的 Tomcat 实例,它也没有被 IntelliJ 接收到。这就是为什么我的更改似乎被忽略了。