Spring интегратор poller vs dispatcher

Я пытаюсь настроить простое приложение с помощью интеграции spring. Цель состоит в том, чтобы просто использовать адаптер входящего канала для отслеживания каталога для новых файлов и файлов процессов по мере их добавления. Для простоты обработка файлов на данный момент является просто протоколированием некоторого вывода (имя обрабатываемого файла). Однако я хочу обрабатывать файлы многопоточным способом. Так что скажем, что 10 файлов собраны и должны обрабатываться параллельно, и как только они будут завершены, мы перейдем к следующим 10 файлам.

Для этого я попробовал два разных подхода и оба, похоже, работают одинаково, и я хотел понять различия между использованием poller или диспетчера для чего-то вроде этого.

Подход №1 - Использование poller

<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" />

Таким образом, идея, которую я понимаю, заключается в том, что мы постоянно проводим опрос в каталоге, и как только файл получен, он отправляется на файлы в канале до тех пор, пока не будет достигнут предел пула. Затем, пока пул не будет занят, никакие дополнительные файлы не будут отправлены, хотя предполагается, что опрос продолжается в фоновом режиме. Это похоже на работу, но я не уверен, что использование максимального количества сообщений в опросе может помочь здесь уменьшить частоту опроса. Установив максимальные сообщения за опрос близко к размеру пула.

Подход №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" />

ok, так что здесь poller не использует исполнителя, поэтому я принимаю его опрос последовательным образом. Каждый опрос 3 файла должен быть поднят, а затем отправлен на файлы. Обратный канал, который затем использует диспетчер для передачи файлов активатору службы, и поскольку он использует диспетчер для диспетчера, он немедленно возвращает управление и позволяет каналу filesIn отправлять больше файлов.

Я предполагаю, что мой вопрос заключается в том, что я правильно понимаю оба подхода, и если один лучше других.

Спасибо

Ответ 1

Да, ваше понимание верное.

Как правило, я бы сказал, что опрос каждой миллисекунды (и отбрасывание опроса при заполнении очереди) - это трата ресурсов (CPU и I/O).

Кроме того, увеличение максимального количества сообщений для каждого опроса в первом случае не поможет, потому что опрос выполняется в потоке исполнителя (планировщик передает опрос исполнителю, и этот поток будет обрабатывать mmpp).

Во втором случае, поскольку поток планировщика отключается во время опроса (а не до него), mmpp будет работать как ожидалось.

Итак, в целом, ваша вторая реализация лучше (если вы можете жить со средней задержкой в ​​2,5 секунды, когда приходит новый файл (ы)).