【问题标题】:Spring File Inbound Channel Adapter slows downSpring File Inbound Channel Adapter 变慢
【发布时间】:2018-06-12 13:05:54
【问题描述】:

我有一个 spring-integration 流程,它从一个由事务轮询器激活的文件入站通道适配器开始(tx 由 atomikos 处理)。 处理文件中的文本并且消息在流中向下传递,直到它被发送到 JMS 队列之一(JMS outbound-channel-adapter)。 在中间,嵌套事务中有一些数据库写入。 该系统旨在 24/7 全天候运行。

碰巧单个消息流逐渐变慢,当我调查时,我发现导致延迟增加的阶段是从文件系统读取。

下面是集成流程的第一部分:

<logging-channel-adapter id="logger" level="INFO"/>
<transaction-synchronization-factory id="sync-factory">
    <after-commit expression="payload.delete()" channel="after-commit"/>
</transaction-synchronization-factory>
<service-activator input-channel="after-commit" output-channel="nullChannel" ref="tx-after-commit-service"/>



<!-- typeb inbound from filesystem -->
<file:inbound-channel-adapter id="typeb-file-inbound-adapter"
                              auto-startup="${fs.typeb.enabled:true}"
                              channel="typeb-inbound"
                              directory="${fs.typeb.directory.in}"
                              filename-pattern="${fs.typeb.filter.filenamePattern:*}"
                              prevent-duplicates="${fs.typeb.preventDuplicates:false}" >
    <poller id="poller"
            fixed-delay="${fs.typeb.polling.millis:1000}"
            max-messages-per-poll="${fs.typeb.polling.numMessages:-1}">
        <transactional synchronization-factory="sync-factory"/>
    </poller>
</file:inbound-channel-adapter>
<channel id="typeb-inbound">
    <interceptors>
        <wire-tap channel="logger"/>
    </interceptors>
</channel>

我阅读了一些关于存储已看到文件列表的 prevent-duplicates 选项相关的问题,但事实并非如此,因为我将其关闭。 我不认为它可能与过滤器(文件名模式)有关,因为我在配置中使用的表达式(*.RCV)很容易应用,并且输入文件夹不包含很多文件(少于 100 ) 同时。

不过,随着时间的推移,有些东西会逐渐使从文件系统读取的速度越来越慢,在正常运行的几天内,从几毫秒到超过 3 秒。

有什么提示吗?

【问题讨论】:

    标签: spring-integration


    【解决方案1】:

    您应该在处理完文件后删除或移动文件;否则必须重新扫描整个目录。

    在较新的版本中,您可以使用更高效的WatchServiceDirectoryScanner

    但清理旧文件仍然是最佳做法。

    【讨论】:

    • 是的,我已经在执行删除操作了(我对此很担心)。如您所见,我对此有一个事务同步,但它没有解决。 &lt;transaction-synchronization-factory id="sync-factory"&gt; &lt;after-commit expression="payload.delete()" channel="after-commit"/&gt; &lt;/transaction-synchronization-factory&gt;
    • 我不愿意使用 WatchServiceDirectoryScanner,因为我担心文件在被放入文件夹的进程完全写入之前会被拾取(更容易)。我知道可以通过主要与作者相关并得到读者支持的方法来防止它,但目前我们没有任何这些方法。
    • payload.delete() 能解决问题吗?交易后文件真的被删除了吗?您能否确认已处理的文件已被删除并且没有介于两者之间?我的意思是确保在使用后关闭文件资源。
    • 这是一个很好的观点。我确信文件已被删除,并且在应用程序的早期生命周期中,它发生得非常快。我认为payload.delete() 不需要对文件进行任何其他最终确定,但我会对此主题进行更好的调查。
    • 好吧,File.delete() 可以返回false,如果文件不能被删除,但没有任何例外。这就是为什么我建议您确保这确实符合您的应用程序的目的。
    【解决方案2】:

    我终于找到了解决方案。 该问题与我使用的特定版本的 Spring (4.3.4) 有关,该版本受我尚未发现的错误的影响。 问题在于 DefaultConversionService 和 converterCache 的使用(查看此以获取更多详细信息https://jira.spring.io/browse/SPR-14929)。 升级到更新版本已解决。

    【讨论】:

      猜你喜欢
      • 2013-07-21
      • 1970-01-01
      • 1970-01-01
      • 2014-12-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多