0

У нас есть процесс java, который прослушивает каталог X в файловой системе, используя apache commons vfs. Всякий раз, когда новый файл экспортируется в этот каталог, происходит наш процесс. Сначала мы переименем файл в filename.processing и проанализируем имя файла, получаем некоторую информацию из файла и вставляем в таблицы перед отправкой этого файла в систему управления документами , Это однопоточное приложение для каждого кластера. Теперь рассмотрим этот запуск в среде кластера, у нас есть 5 серверов. Таким образом, 5 разных виртуальных машин пытаются получить доступ к одному файлу. Вся реализация была основана на том, что только один процесс может переименовать файл в .processing в данный момент времени, так как ОС не позволит нескольким процессам изменять файл одновременно. После того, как кластер get удерживает и переименовывает файл в .processing, другие кластеры будут игнорировать файлы, имеющие формат .processing.Java-кластер, запускать задачу только один раз

Это работало отлично с более чем года, но сейчас мы обнаружили несколько дубликатов. Похоже, что несколько кластеров захватили файл, в этом случае говорят, что кластер a, b, c получил доступ к файлу f.pdf, и они переименовали его в f.pdf.processing в одно и то же время (я все еще сбитый с толку как ОС позволяет одновременно изменять файл). В результате этого кластер a, b, c они обработали файл и отправили его в систему управления документами. Итак, теперь есть 3 дубликата файлов.

Итак, вкратце, что я ищу, подходит для запуска задачи только один раз в среде кластера. Я также хочу, чтобы у него был механизм переключения, поэтому, если что-то пошло не так с кластером, другой кластер возьмет задачу. Мы не хотим устанавливать переменную env, как master = true в поле, поскольку это ограничит ее только одним кластером и не будет обрабатывать переход на другой ресурс.

Любые виды помощи приветствуются.

+0

Есть ли версия tl; dr? –

+0

Выполняет ли ваше приложение много мелких файлов или несколько больших? Я имею в виду, можно ли дождаться некоторого количества времени до начала обработки или вызвать проблемы с производительностью? – user3707125

+0

Это кажется очень склонным к ошибкам, даже если сделано правильно. Вы должны посмотреть на Амазонки SQS, чтобы увидеть, как они управляют задачами, и либо использовать это, либо реализовывать что-то подобное. – nikdeapen

ответ

1

Мы реализуем собственную логику синхронизации, используя общую таблицу блокировки внутри базы данных приложения. Это позволяет всем узлам кластера проверять, запущено ли задание, прежде чем запускать его сам.

1

Смотрите следующую запись о блокировке файла: How do filesystems handle concurrent read/write?

операция чтения и записей (которая включает в себя переименование) файлы не являются атомарными и не очень хорошо синхронизированы между процессами, как вы предположить, - по крайней мере, не так в большинстве операционных системы.

Однако создание нового файла обычно является атомной операцией. Вы можете использовать это в своих интересах. Концепция называется цельной блокировкой файлов.

+0

Спасибо, как я могу получить блокировку целых файлов с помощью java-кода? В приведенном выше ответе Вячеслав выделил VFSUtils, в котором есть метод блокировки покупки. Интересно, будет ли это работать? https://synapse.apache.org/apidocs/org/apache/synapse/transport/vfs/VFSUtils.html –

0

Вы пытаетесь использовать FileLock tryLock() или lock() перед переименованием файла в .processing? Если вы этого не сделали, я думаю, вы должны попробовать, поэтому в этом случае только одно приложение может изменить этот файл.

Обновление: Извините, я забыл, что вы спрашиваете о VDF. В Apache VDF (на самом деле, в Apache Synapse) я нашел VFSUtils класс, которые следующий метод:

public static boolean acquireLock(org.apache.commons.vfs2.FileSystemManager fsManager, 
            org.apache.commons.vfs2.FileObject fo) 

Acquires a file item lock before processing the item, guaranteing that the file is not processed while it is being uploaded and/or the item is not processed by two listeners 
Parameters: 
    fsManager - used to resolve the processing file 
    fo - representing the processign file item 
Returns: 
    boolean true if the lock has been acquired or false if not 

Я думаю, что метод может решить ваши проблемы (если вы можете использовать Apache Synapse в вашем проекте).

+0

Как можно применить FileLock к Apache VFS? – user3707125

+0

Я исправил свой ответ –

+0

@ViacheslavVedenin Спасибо за внимание. Я попробую ваше решение и дам вам знать, будет ли это работать для меня. Мне нужно добавить зависимость Synapse для этого, что удивительно, что эта функциональность не является частью apache vfs. Так что для моего понимания, если один кластер получает эту блокировку, тогда, когда другой кластер пытается получить, я надеюсь, что этот метод вернет false? –

Смежные вопросы