Обработка текстовых файлов, переданных по ftp в набор каталогов на размещенном сервере

StackOverflow https://stackoverflow.com/questions/208772

Вопрос

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

Ряд удаленных рабочих станций собирает полевые данные и передает их по ftp на сервер через ftp.Данные отправляются в виде CSV-файла, который хранится в уникальном каталоге для каждой рабочей станции на FTP-сервере.

Каждая рабочая станция отправляет новое обновление каждые 10 минут, в результате чего предыдущие данные перезаписываются.Мы хотели бы каким-то образом объединить или сохранить эти данные автоматически.Обработка данных рабочей станции ограничена и не может быть расширена, поскольку это встроенная система.

Одним из предложенных предложений было запустить cronjob на FTP-сервере, однако в Условиях предоставления услуг существует ограничение разрешать cronjobs только с интервалом в 30 минут, поскольку это общий хостинг.Учитывая количество загружаемых рабочих станций и 10-минутный интервал между загрузками, похоже, что 30-минутный лимит cronjob между вызовами может быть проблемой.

Есть ли какой-либо другой подход, который можно было бы предложить?Доступными языками написания сценариев на стороне сервера являются perl, php и python.

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

Это было полезно?

Решение

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

Редактировать:Что касается приведенного ниже комментария Марка Бейкера :

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

Это произойдет с функцией inotify watch, которую вы установили на уровне каталога - способ убедиться, что вы не заберете частичный файл, - это установить дополнительную функцию inotify watch для нового файла и искать событие IN_CLOSE, чтобы вы знали, что файл был записан полностью.

Как только ваш процесс увидит это, вы можете удалить inotify watch из этого нового файла и обработать его на досуге.

Другие советы

Вы могли бы рассмотреть постоянный демон, который продолжает опрашивать целевые каталоги:

grab_lockfile() or exit();
while (1) {
    if (new_files()) {
        process_new_files();
    }
    sleep(60);
}

Тогда ваше задание cron может просто пытаться запускать демон каждые 30 минут.Если демон не может захватить файл блокировки, он просто умирает, так что можно не беспокоиться о запуске нескольких демонов.

Другим подходом, который следует рассмотреть, была бы отправка файлов через HTTP POST, а затем обработка их с помощью CGI.Таким образом, вы гарантируете, что с ними было сделано все должным образом на момент отправки.

30-минутное ограничение на самом деле довольно глупо.Запуск процессов в linux не является дорогостоящей операцией, поэтому, если все, что вы делаете, это проверяете наличие новых файлов, нет веских причин не делать это чаще.У нас есть задания cron, которые выполняются каждую минуту, и они не оказывают какого-либо заметного влияния на производительность.Однако я понимаю, что это не ваше правило, и если вы собираетесь придерживаться этого хостинг-провайдера, у вас нет выбора.

Вам понадобится какой-нибудь долго работающий демон.Самый простой способ - просто регулярно проводить опросы, и, вероятно, именно это я бы и сделал.Лучшим вариантом является Inotify, чтобы вы получали уведомления сразу после создания файла.

Вы можете использовать inotify из perl с Linux::Inotify или из python с pyinotify.

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

При опросе менее вероятно, что вы увидите неполные файлы, но рано или поздно это произойдет, и когда это произойдет, это будет неприятная трудновоспроизводимая ошибка, поэтому лучше разобраться с проблемой сейчас.

Если вы хотите сохранить существующую настройку FTP-сервера, я бы посоветовал использовать что-то вроде inotify или daemonized process для просмотра каталогов загрузки.Если вас устраивает переход на другой FTP-сервер, вы могли бы взглянуть на pyftpdlib который представляет собой библиотеку FTP-сервера Python.

Я некоторое время был частью команды разработчиков pyftpdlib, и одним из наиболее распространенных запросов был способ "обрабатывать" файлы после завершения их загрузки.Из-за этого мы создали on_file_received() метод обратного вызова, который запускается по завершении загрузки (см. выпуск №79 подробности в нашем сервисе отслеживания проблем).

Если вы хорошо разбираетесь в Python, то вам может быть полезно запустить pyftpdlib в качестве вашего FTP-сервера и запустить код обработки из метода обратного вызова.Обратите внимание, что pyftpdlib является асинхронным, а не многопоточным, поэтому ваш метод обратного вызова не может блокировать.Если вам нужно запускать длительные задачи, я бы рекомендовал использовать отдельный процесс или поток Python для фактической обработки.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top