spring integration poller vs dispatcher

ade*_*ood 14 spring-integration

我正在尝试使用spring集成设置一个简单的应用程序.目标是简单地使用文件入站通道适配器来监视目录中的新文件和处理文件.为简单起见,此时处理文件只是记录一些输出(正在处理的文件的名称).但我想以多线程方式处理文件.因此,假设有10个文件被拾取并且应该并行处理,一旦完成这些文件,我们就会转到接下来的10个文件.

为此我尝试了两种不同的方法,两者似乎都工作方式相似,我想了解使用poller或dispatcher之间的区别.

方法#1 - 使用轮询器

<int-file:inbound-channel-adapter id="filesIn" directory="in">
        <int:poller fixed-rate="1" task-executor="executor" />
</int-file:inbound-channel-adapter>

<int:service-activator ref="moveToStage" method="move" input-channel="filesIn" />

<task:executor id="executor" pool-size="5" queue-capacity="0" rejection-policy="DISCARD" />
Run Code Online (Sandbox Code Playgroud)

所以在这里,我理解的想法是我们不断轮询目录,一旦收到文件,它就会发送到filesIn通道,直到达到池限制.然后,直到池被占用,即使我假设轮询仍在后台继续,也不会发送其他文件.这似乎有效,但我不确定使用每次轮询的最大消息是否有助于降低轮询频率.通过将每个轮询的最大消息数设置为接近池大小.

方法#2 - 使用调度程序

<int-file:inbound-channel-adapter id="filesIn" directory="in">
    <int:poller fixed-rate="5000" max-messages-per-poll="3" />
</int-file:inbound-channel-adapter>

<int:bridge input-channel="filesIn" output-channel="filesReady" />

<int:channel id="filesReady">
    <int:dispatcher task-executor="executor"/>
</int:channel>

<int:service-activator ref="moveToStage" method="move" input-channel="filesInReady" />

<task:executor id="executor" pool-size="5" queue-capacity="0" rejection-policy="CALLER_RUNS" />
Run Code Online (Sandbox Code Playgroud)

好吧所以这里轮询器没有使用执行器,所以我假设它以顺序方式进行轮询.应该拾取每个poll 3文件,然后发送到filesReady通道,然后使用调度程序将文件传递给服务激活器,因为它使用执行程序进行调度,它立即返回控制并允许filesIn通道发送更多文件.

我想我的问题是我是否正确理解这两种方法,如果一种方法比其他方法更好.

谢谢

Gar*_*ell 8

是的,你的理解是正确的.

通常,我会说每轮毫秒轮询(并在队列满时丢弃轮询)是浪费资源(CPU和I/O).

此外,在第一种情况下增加每个轮询的最大消息将无济于事,因为轮询是在执行程序线程上完成的(调度程序将轮询移交给执行程序,并且该线程将处理该轮询mmpp).

在第二种情况下,由于调度程序线程在轮询期间(而不是在它之前)切换,因此mmpp将按预期工作.

因此,一般来说,您的第二个实现是最好的(只要您在新文件到达时平均延迟2.5秒).