在使用聚合器时了解线程池

时间:2014-02-11 19:56:59

标签: spring-integration

我试图在高层次上理解线程分配如何在spring集成流程中发生,特别是在使用aggreagtor时。为了提供一些上下文,我的流程看起来像这样

从目录轮询文件
使用执行程序通道接收轮询文件
聚合轮询文件,直到满足某些标准为止 将聚合文件发布到后续通道,该通道处理所有聚合文件 拆分文件
归档单个文件

此配置的主要目标是将轮询过程与流程中的后续步骤分离。我希望能够在处理现有文件时继续轮询和加载文件。所有这一切都可以正常使用执行程序通道,但一旦达到线程池限制,如果让我们说轮询器线程因CALLER_RUNS拒绝策略而最终被卡住,那么我必须等到这个线程完成才能返回轮询更多文件。

好的,回到我真正的问题,即了解如何在这样的流程中分配线程。因此,poller将文件撤消,将其传递给使用调度程序的执行程序通道,从而创建一个新线程来处理传入文件。现在,一旦这个文件卡在聚合器中,这个线程会发生什么。线程是否已完成/已关闭,因为文件已到达其当前的最终目标。

然后一旦达到聚合器限制并且所有文件都被发送到下一个通道,我假设在新的/单个线程中发生,但是当我们使用拆分器时,它然后为每个拆分文件创建一个新线程。这是正确的。

如果这有点令人困惑,我很抱歉。我真的只是更好地理解这个过程,因为我不喜欢这个设置(我的配置)几乎每次流都在聚合器之后的步骤卡住,这是自处理所有聚合文件以来耗时的步骤..它的大部分CALLER_RUNS最终执行耗时的步骤..然后基本上停止轮询过程,直到这个耗时的步骤完成。

我也会发布我的配置xml,但基本上我希望通过更好地理解线程分配过程,我可以稍微调整一下,而不是使聚合文件处理步骤成为瓶颈。

<!-- Poll files from landing zone directory -->
<int-file:inbound-channel-adapter id="files" directory="${lz.dir.${ft}}" filename-regex=".*\.txt$">
    <int:poller fixed-delay="3000" max-messages-per-poll="10"  />
</int-file:inbound-channel-adapter>

<int:bridge input-channel="files" output-channel="sourceFiles" />

<!-- Dispatch retrieved files -->
<int:channel id="sourceFiles">
    <int:dispatcher task-executor="executor" />
</int:channel>

<!-- Move files to source directory -->
<int:service-activator  input-channel="sourceFiles"
                        output-channel="sourceFilesProcessed" 
                        ref="moveToSource" 
                        method="move" />

<int:channel id="sourceFilesProcessed" />

<!-- Aggregate at source -->
<int:aggregator id="filesBuffered" 
                input-channel="sourceFilesProcessed"
                output-channel="stagedFiles"
                release-strategy-expression="size() >= 500 and !@moveToStageAndTarget.isRunning()" 
                correlation-strategy-expression="'mes-group'" 
                expire-groups-upon-completion="true" 
                />

<int:channel id="stagedFiles" />

<!-- Process aggregated source files -->
<int:chain input-channel="stagedFiles">
    <!-- Move stage files to target -->
    <int:service-activator  ref="moveToStageAndTarget" method="move" />

    <!-- Split files back into individual file -->
    <int:splitter />

    <!-- Archice each file -->
    <int:service-activator ref="archiveFiles" method="archive" />           
</int:chain>    

<task:executor id="executor" pool-size="100" queue-capacity="0" rejection-policy="CALLER_RUNS" />

1 个答案:

答案 0 :(得分:1)

  1. 使用queue-capacity="0"是不好的。请看一下ThreadPoolTaskExecutor的JavaDocs。 因此,坚持实际上是SynchronousQueue

  2. 建议使用ExecutorChannel作为<splitter>的输出,只要它产生多个Messages,在您的情况下,它们现在都在同一个Thread内处理{1}}一个接一个。

  3. 聚合器不依赖于线程,但需要记住,发布一个Thread内的一个组,其Message对{ {1}} release-strategy。因此,这是另一个案例,为什么你坚持