Spring integration 使用聚合器时了解线程池
我试图从更高的层次理解spring集成流中线程分配是如何发生的,尤其是在使用aggreator时。为了提供一些上下文,我的流程如下所示 从目录轮询文件Spring integration 使用聚合器时了解线程池,spring-integration,Spring Integration,我试图从更高的层次理解spring集成流中线程分配是如何发生的,尤其是在使用aggreator时。为了提供一些上下文,我的流程如下所示 从目录轮询文件 使用执行器通道接收轮询文件 聚合轮询的文件,直到满足某些条件 将聚合文件释放到后续通道,该通道处理所有聚合文件 拆分文件 归档单个文件 此配置的主要目标是将轮询过程与流中的后续步骤分离。我希望能够在处理现有文件时继续轮询和加载文件。使用executor通道可以很好地工作,但是一旦达到线程池限制,并且如果说轮询器线程由于CALLER_运行拒绝策略而
使用执行器通道接收轮询文件
聚合轮询的文件,直到满足某些条件
将聚合文件释放到后续通道,该通道处理所有聚合文件
拆分文件
归档单个文件
此配置的主要目标是将轮询过程与流中的后续步骤分离。我希望能够在处理现有文件时继续轮询和加载文件。使用executor通道可以很好地工作,但是一旦达到线程池限制,并且如果说轮询器线程由于CALLER_运行拒绝策略而被卡住,那么我必须等待该线程完成,然后才能返回轮询更多文件 好的,现在回到我真正的问题,那就是理解线程是如何在这样的流中分配的。因此轮询器重定时一个文件,将其传递给执行器通道,执行器通道使用一个分派器,因此创建一个新线程来处理传入的文件。现在,一旦这个文件卡在聚合器中,这个线程会发生什么情况。线程是否已完成/关闭,因为文件已到达其当前最终目标 一旦达到聚合器限制,所有文件都被发送到下一个通道,我假设这发生在一个新的/单个线程中,但当我们使用拆分器时,它会为每个拆分文件创建一个新线程。对吗 如果这有点混乱,我很抱歉。我真的只是稍微了解了一下这个过程,因为我不喜欢这个设置(我的配置),因为几乎每次流在聚合器之后的步骤卡住时,这是一个耗时的步骤,因为它处理所有聚合的文件。。大多数调用方_运行,最终执行耗时的步骤。。然后基本上停止轮询过程,直到完成这个耗时的步骤 我还将发布我的配置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" />
队列容量=“0”
是不好的。请看一下的JavaDocs。
因此,您的粘滞实际上是在SynchronousQueue
ExecutorChannel
作为
的输出,只要它生成多条消息
,在您的情况下,现在它们都在同一线程中逐个处理
线程中的一个组,其消息表示释放策略
。所以,这是另一种情况,为什么你会粘在一起
不确定队列容量会有什么帮助,因为如果我假设将最大池大小更改为50,将队列容量更改为50,那么最终结果将与最大池大小为100相同。对于拆分器来说,这很有意义,但我认为在我的情况下,让一个线程从拆分器按顺序处理所有文件是可以的,因为这一步非常快,我还可以在流程中保留其他进程使用的线程池。另一个建议是将
聚合器的输出通道更改为队列。无论如何,SynchronousQueue
是坏的。它等待提供
,然后另一个线程将不会通过设置聚合器的输出通道来执行拉
,这将有什么不同/更好的地方。。我的意思是,聚合器(消息集合)只发送一条消息。。只是想了解你的观点。我将尝试更改队列容量以查看其行为。再次感谢:聚合器不依赖于线程,而是在封闭的线程中发送结果。只要它是一个从你的线程池,并没有在下游流偏差,所有的工作将在该线程内完成。但是这里有一个关于同步队列的问题。这就是为什么轮询任务是粘滞的原因抱歉,我说的是拆分器输出通道是执行器,而不是聚合器,但我明白了一般的想法,我会尝试使用队列大小,看看什么效果更好。谢谢