Вопрос или проблема
Я выполняю загрузку файлов в Akamai Netstorage через SFTP в автоматизированном рабочем процессе. Я заметил, что загрузка SFTP происходит параллельно (к сожалению, это трудно надежно предотвратить) и завершается неудачно, так как они пытаются записать в один и тот же файл на сервере одновременно. Сервер возвращает код статуса 409 одному из запущенных загрузок, и файл, в который производится запись, остается пустым (нулевой байт) по завершении обеих загрузок.
Когда я пытаюсь повторно запустить задание SFTP, оно не перезаписывает пустой файл правильным содержимым, а видит, что файл уже существует, и пропускает его.
Я использую lftp (готов перейти на любой другой SFTP-клиент) и хотел бы решить эту проблему так, чтобы одна из параллельных загрузок была успешной и результирующий файл не был нулевым байтом.
Команда lftp имеет очень много опциональных аргументов, которые могут или не могут помочь. Они не очень хорошо документированы. Я был бы признателен за любые советы от тех, кто сталкивался с такой ситуацией ранее и нашел хорошее решение.
Ответ или решение
Для предотвращения создания файлов нулевого размера при загрузке через SFTP на Akamai Netstorage, необходимо учесть несколько ключевых аспектов, особенно в условиях параллельных загрузок, которые могут приводить к конфликту.
1. Использование блокировок
Первое, что стоит рассмотреть — это метод механизма блокировок на уровне приложения. Если возможно, организуйте очередь загрузок, которая будет обеспечивать последовательное выполнение операций. Это может быть сделано с помощью:
- Механизма блокировки на уровне базы данных (если это применимо).
- Внедрения простейшего механизма очереди в вашем сценарии.
Если использование очередей невозможно, то следует предусмотреть периодическую проверку состояния файлов перед загрузкой.
2. Условные загрузки
Если это возможно в вашем пути, используйте метод условной загрузки. Ниже представлен алгоритм:
- Перед загрузкой файла проверьте, существует ли уже файл на сервере с тем же именем.
- Если файл существует, запросите его размер (с помощью команды
ls
или аналогичной). Если размер 0, то продолжите загрузку. Если размер больше 0, пропустите загрузку. - Вы можете использовать такие команды lftp, как
-e "stat имя_файла"
для получения информации о файле.
3. Параметры lftp
Также стоит протестировать некоторые параметры lftp, которые могут помочь избежать этого конфликта. Основные рекомендации:
- Используйте
-c
(continue) при загрузке, чтобы продолжить работу даже в случае какого-либо конфликта. - Попробуйте ограничить параллелизм за счет использования параметра
--parallel=1
, чтобы ограничить количество одновременно выполняемых операций загрузки.
Пример команды:
lftp -u USER,PASSWORD sftp://yourserver.com -e "set net:idle 10; set net:max-retries 3; set net:retries 3; put файл.txt; bye"
4. Обработка ошибок
Настройте ваш скрипт на обработку случаев, когда возникает ошибка 409. Например, если получен конфликт:
- Логируйте эту ошибку и подождите некоторое время (например, 30 секунд), прежде чем повторить попытку загрузки.
- Добавьте логику повторной загрузки, которая проверит размер файла и предоставит дополнительное время для завершения предыдущей операции.
Заключение
Сочетание управления параллельными загрузками, проверок на существование и размере файла, а также грамотная обработка ошибок помогут вам избежать создания пустых файлов на сервере. Настройте параметры lftp, чтобы лучше соответствовать вашим конкретным потребностям, и поддерживайте надежный механизм обработки ошибок. Эти шаги могут значительно повысить надежность вашего процесса загрузки.