sFTP с несколькими потребителями и идемпотентными маршрутами: исключения файлов - PullRequest
0 голосов
/ 09 января 2020

У меня есть пара маршрутов Camel, которые обрабатывают файлы, расположенные на сервере sFTP. В приложении есть несколько узлов, на которых расположены маршруты, поэтому я добавил блокировку файлов, чтобы гарантировать, что каждый файл обрабатывает только один узел.

URI маршрута выглядит следующим образом (для удобства чтения разделен на несколько строк):

sftp://<user>@<server>:<port>/<folder>
    ?password=<password>
    &readLock=changed
    &readLockMinAge=10s
    &delete=true
    &delay=60s
    &include=<file mask>

Маршрут выглядит следующим образом:

from(inUri) //
    .id("myId") //
    .idempotentConsumer(header(Exchange.FILE_NAME), messageIdRepository) //
    .eager(true) //
    .skipDuplicate(true) //
    .log(LoggingLevel.INFO, "Processing file:  ${file:name}") //
    // Save original file in archive directory.
    .to(archiveUri) //
    ... do other stuff...

Время от времени я получаю то, что выглядит как предупреждение о конфликте файлов:

Error processing file RemoteFile[<file>] due to Cannot retrieve file: <file>. Caused by:
[org.apache.camel.component.file.GenericFileOperationFailedException - Cannot retrieve file: <file>]
org.apache.camel.component.file.GenericFileOperationFailedException: Cannot retrieve file: <file>
Caused by: com.jcraft.jsch.SftpException: No such file

... а также эти:

Error during commit. Caused by: [org.apache.camel.component.file.GenericFileOperationFailedException - Cannot delete file: <file>]
org.apache.camel.component.file.GenericFileOperationFailedException: Cannot delete file: <file>
Caused by: com.jcraft.jsch.SftpException: No such file

Я что-то пропустил в своей настройке?

Я пытался добавить идемпотентный репозиторий во входной URI, например:

sftp://<user>@<server>:<port>/<folder>
    ?password=<password>
    &readLock=changed
    &readLockMinAge=<minAge>
    &delete=true&delay=<delay>
    &include=<file mask>
    &idempotent=true
    &idempotentKey=$simple{file:name}
    &idempotentRepository=#messageIdRepository

... но я получаю такие же ошибки.

Я использую Apache Camel версии 2.24.2.

1 Ответ

0 голосов
/ 10 января 2020

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

Обычно эти ошибки "просто" поступают от одного узла, который пытается обработать уже обработанный (и, следовательно, удаленный) файл . Таким образом, они не являются реальной проблемой , и если вы можете жить с ними, ваша установка, вероятно, работает правильно (файлы на самом деле не обрабатываются несколько раз).

Я обычно делаю

  • Используйте опции initialDelay и delay для , чтобы все узлы не опрашивались одновременно
  • Используйте параметр shuffle=true, чтобы каждый клиент случайным образом перемешивал список файлов . Это снижает вероятность того, что все клиенты попытаются обработать один и тот же файл

Они также ненадежны, в лучшем случае могут быть улучшением.

Единственный способ надежно избежать обработки один и тот же файл с несколькими узлами, возможно, использует только один потребитель . Мы используем эту настройку в комбинации с проверками работоспособности и автоматическими c перезапусками , чтобы убедиться, что единственный потребитель доступен.

Обратите внимание, что добавление идемпотентного репозитория стоит ничего, пока вы не используете распределенный репозиторий , как hazelcast. Если вы используете только локальный репозиторий (или просто репозиторий в памяти), он индивидуален для каждого узла и поэтому просто избегает, чтобы один и тот же клиент обрабатывал один и тот же файл несколько раз.

Обновление из-за комментария

Когда вы получили распределенное идемпотентное хранилище и файлы были обработаны несколько раз, хранилище не работает. Я могу только предположить некоторые вещи, которые могут быть источником

  • Хранилище ничего не делает (проверка записей)
  • Вы должны установить readLock в idempotent, чтобы «включить» хранилище для файлового компонента
  • По тем или иным причинам один и тот же файл из разных узлов имеет разные идентификаторы идемпотентности (проверьте в своем репо), и поэтому они не распознаются как дубликаты

К сожалению, idempotent Настройка readLock поддерживается только для файлового компонента , но не для компонента FTP .

Существует также inProgressRepository. Вы также можете попытаться прикрепить свой репозиторий с этой опцией.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...