【问题标题】:Spring Integration File Polling. If moving the file does a AcceptOnceFileListFilter need to be used?Spring 集成文件轮询。如果移动文件,是否需要使用 AcceptOnceFileListFilter?
【发布时间】:2015-04-03 21:39:53
【问题描述】:

我正在编写一个文件轮询实现并试图确定是否需要使用 AcceptOnceFileListFilter。 FileProcessor 将执行的第一步是将文件移动到另一个目录。

轮询器“batchFilePoller”在轮询时是否使用多个线程?一个文件将被多个线程读取的情况下会出现竞争条件吗?在这种情况下,我假设我需要使用 AcceptOnceFileListFilter。

但是,如果轮询器仅使用池中的一个线程。 那么如果文件在下一个轮询时间之前移动并且它成功了,我假设文件没有被处理两次的可能性?

<int-file:inbound-channel-adapter id="batchFileInAdapter" directory="/somefolder" auto-create-directory="true" auto-startup="false" channel="batchFileInChannel" >
    <int:poller id="batchFilePoller" fixed-rate="6000" task-executor="batchTaskExecutor" max-messages-per-poll="1" error-channel="batchPollingErrorChannel" />
</int-file:inbound-channel-adapter>

<int:channel id="batchFileInChannel"/>

<int:service-activator input-channel="batchFileInChannel" >
    <bean class="com.foo.FileProcessor" />
</int:service-activator>

<task:executor id="batchTaskExecutor" pool-size="5" queue-capacity="20"/>

【问题讨论】:

    标签: multithreading spring spring-integration file-processing


    【解决方案1】:

    &lt;int-file:inbound-channel-adapter&gt; 具有 prevent-duplicates 选项,默认为 true,这是您的情况,因为您没有提供任何其他选项来阻止 prevent-duplicates 成为 true

    是的:如果您使用fixed-rate,任何轮询适配器都是多线程的。在这种情况下,新的轮询任务可以在前一个任务完成之前运行。

    即使它是单线程的(使用fixed-delay),AcceptOnceFileListFilter 也必须存在,因为新的轮询任务不知道文件是否已被处理。它会再次读取同一个文件。

    AcceptOnceFileListFilter 正好适用于您不想再读取同一个文件的情况。您可以使用&lt;int:transactional synchronization-factory=""/&gt; 来克服&lt;int-file:inbound-channel-adapter&gt;&lt;poller&gt; 的问题:

    <int:transaction-synchronization-factory id="txSyncFactory">
        <int:after-commit expression="payload.delete()"/>
    </int:transaction-synchronization-factory>
    

    PseudoTransactionManager

    您可以在 Spring 集成参考手册中找到更多信息。

    【讨论】:

    • 好的,如果第一个线程在 6 秒内没有完成它的工作,另一个线程会从池中被抓取吗?我想只要在这六秒内移动文件,就不会再次读取它。这是一个风险,但在这种情况下,可以设置 prevent-duplicates="false"。这当然是在处理重复项没问题的情况下。
    • 是的。但请注意,您使用task-executor,因此不会从TaskScheduler 中获取更多线程来进行轮询任务。这是因为第一个 poll 将消息转移到 task-executor 并完成其工作,将线程返回到 TaskScheduler 池。再说一遍:参考手册中对此进行了描述。
    • 感谢 Artem,我现在有了更好的理解。我将使用固定延迟并允许重复。该文件将作为轮询的一部分被移动,然后移交给另一个任务执行器进行处理。
    • Artem,如何配置它以在将工作转移到的任务执行器完成之前从任务调度器中获取更多线程?
    • 听起来像是一个单独的问题。而且我不确定:担心来自 TaskShceduler 的更多线程对我来说是没有意义的。
    猜你喜欢
    • 2020-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-06
    • 2017-10-26
    • 2019-11-24
    • 2020-07-12
    相关资源
    最近更新 更多