【问题标题】:IntegrationFlows with FileReadingMessageSource triggering job twice for same input file具有 FileReadingMessageSource 的 IntegrationFlows 两次为同一输入文件触发作业
【发布时间】:2019-05-09 07:50:21
【问题描述】:

我有一个 Spring Integration Batch 作业,当文件到达时触发:

@Bean
public IntegrationFlow fileTriggeredIntegrationFlow() {
    return IntegrationFlows.from(fileReadingMessageSource(),
            c -> c.poller(Pollers.fixedRate(filePollerFrequency, filePollerInitialDelay)))
            .transform(toJobLaunchRequest())
            .handle(jobLaunchingGateway)
            .handle("jobCompletionHandler", "afterJob")
            .get();
}

@Bean
public FileReadingMessageSource fileReadingMessageSource() {
    FileReadingMessageSource sourceReader = new FileReadingMessageSource();
    log.info("Listening for {} files at {}", sourceFilePattern, sourceFileDirectory);
    sourceReader.setDirectory(new File(sourceFileDirectory));
    sourceReader.setFilter(new RegexPatternFileListFilter(sourceFilePattern));
    return sourceReader;
}

长期以来一直非常顺利,但最近我遇到了相同输入文件的作业运行两次的问题。以下是来自日志文件的 sn-p:

2018-12-06 13:52:32,595 INFO [task-scheduler-7] osifFileReadingMessageSource:380 - 创建消息:[GenericMessage [payload=/local/MY_INPUT_FILE.DAT, headers= {id=ba1ad258-72cf-ed07-1175-3d1cc36f9bc1,时间戳=1544122352595}]]

2018-12-06 13:52:32,599 INFO [task-scheduler-10] osifFileReadingMessageSource:380 - 创建消息:[GenericMessage [payload=/local/MY_INPUT_FILE.DAT, headers= {id=ab8e9fbc-72a1-43e0-2ca3-8b8dcb3d91e5,时间戳=1544122352599}]]

如果您看到有两个以粗体标记的线程,它们拾取了相同的文件并两次触发了相同的作业。有人可以指导我如何避免这些情况吗?

【问题讨论】:

    标签: java spring multithreading spring-integration spring-batch


    【解决方案1】:

    看起来在下一个轮询周期中从sourceFileDirectory 目录中提取了同一个文件。

    您需要考虑在CompositeFileListFilterChainFileListFilter 中使用AcceptOnceFileListFilterRegexPatternFileListFilter 作为组合:https://docs.spring.io/spring-integration/docs/current/reference/html/files.html#file-reading

    【讨论】:

    • 感谢您的帮助。我还想对此进行测试以避免生产中的任何问题。我怎样才能得到这个测试?
    • 您可以查看 Spring 集成测试框架:docs.spring.io/spring-integration/docs/current/reference/html/…。我猜你需要像MockIntegration.mockMessageHandler() 这样来验证你的FileReadingMessageSource 只生成一个文件。
    • 我在某个位置创建了一个有效文件并检查了是否使用 fileReadingMessageSource.receive() 读取了该文件,之后我删除了该文件并创建了具有相同名称的文件并检查了 fileReadingMessageSource.receive() 是否返回空。
    猜你喜欢
    • 2014-03-04
    • 1970-01-01
    • 1970-01-01
    • 2013-07-03
    • 2011-12-20
    • 1970-01-01
    • 1970-01-01
    • 2017-07-19
    • 1970-01-01
    相关资源
    最近更新 更多