Traiter les fichiers texte ftp dans un ensemble de répertoires sur un serveur hébergé

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

Question

La situation est la suivante:

Une série de stations de travail distantes collecte les données de champ et ftp les données collectées sur un serveur via ftp. Les données sont envoyées sous la forme d’un fichier CSV stocké dans un répertoire unique pour chaque poste de travail du serveur FTP.

Chaque poste de travail envoie une nouvelle mise à jour toutes les 10 minutes, ce qui écrase les données précédentes. Nous souhaitons concaténer ou stocker ces données automatiquement. Le traitement du poste de travail est limité et ne peut pas être étendu car il s'agit d'un système intégré.

Une suggestion proposée consistait à exécuter une tâche cron dans le serveur FTP. Toutefois, il existe une restriction relative aux conditions de service qui autorise uniquement les tâches cron dans des intervalles de 30 minutes car il s'agit d'un hébergement partagé. Compte tenu du nombre de postes de travail mis en ligne et de l'intervalle de 10 minutes entre les envois, il semble que la limite de 30 minutes établie par cronjob puisse poser problème.

Existe-t-il une autre approche qui pourrait être suggérée? Les langages de script côté serveur disponibles sont perl, php et python.

Une mise à niveau vers un serveur dédié peut être nécessaire, mais j'aimerais tout de même savoir comment résoudre ce problème de la manière la plus élégante qui soit.

Était-ce utile?

La solution

La plupart des systèmes Linux modernes prendront en charge inotify pour permettre à votre processus de savoir quand le contenu d'un répertoire a été modifié, de sorte que vous n'avez même pas besoin d'interroger.

Modifier: en ce qui concerne le commentaire ci-dessous de Mark Baker:

"Soyez prudent, vous serez averti dès la création du fichier, pas quand il sera fermé. Vous aurez donc besoin d’un moyen de vous assurer que vous ne récupérerez pas de fichiers partiels. "

Cela se produira avec la surveillance inotify que vous définissez au niveau du répertoire. Pour vous assurer de ne pas récupérer le fichier partiel, vous devez définir une surveillance inotify supplémentaire sur le nouveau fichier et rechercher l'événement IN_CLOSE afin que vous savez que le fichier a été complètement écrit.

Une fois que votre processus en a eu connaissance, vous pouvez supprimer la surveillance inotify de ce nouveau fichier et la traiter à votre guise.

Autres conseils

Vous pourriez envisager un démon persistant qui continue à interroger les répertoires cibles:

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

Ensuite, votre tâche cron peut simplement essayer de démarrer le démon toutes les 30 minutes. Si le démon ne parvient pas à récupérer le fichier lock, il mourra. Vous n'avez donc pas à vous soucier de l'exécution de plusieurs démons.

Une autre approche à envisager serait de soumettre les fichiers via HTTP POST, puis de les traiter via un fichier CGI. De cette façon, vous garantissez qu’ils ont été traités correctement au moment de la soumission.

La limite de 30 minutes est vraiment ridicule. Démarrer des processus sous Linux n'est pas une opération coûteuse. Si vous ne faites que rechercher de nouveaux fichiers, vous n'avez aucune raison de ne pas le faire plus souvent. Nous avons des tâches cron qui fonctionnent toutes les minutes et qui n’ont aucun effet notable sur les performances. Cependant, je me rends compte que ce n’est pas votre règle et que si vous vous en tenez à ce fournisseur d’hébergement, vous n’avez pas le choix.

Vous aurez besoin d’un démon long. Le moyen le plus simple est de procéder à des sondages réguliers, et c'est probablement ce que je ferais. Inotify, afin que vous soyez averti dès qu'un fichier est créé, est une meilleure option.

Vous pouvez utiliser inotify à partir de perl avec Linux :: Inotify ou de python avec pyinotify.

Faites attention cependant, vous serez averti dès la création du fichier, pas quand il sera fermé. Vous aurez donc besoin d’un moyen de vous assurer que vous ne récupérez pas de fichiers partiels.

Avec l'interrogation, il est moins probable que vous voyiez des fichiers partiels, mais cela finira par se produire et il s'agira d'un bogue difficile à reproduire lorsque cela se produira, il est donc préférable de traiter le problème maintenant.

Si vous souhaitez conserver la configuration existante de votre serveur FTP, je vous conseillerais d'utiliser un processus tel que inotify ou démonisé pour surveiller les répertoires de téléchargement. Si vous souhaitez passer à un autre serveur FTP, consultez pyftpdlib qui est une bibliothèque de serveur FTP Python.

Je fais partie de l'équipe de développement de pyftpdlib depuis un certain temps et l'une des demandes les plus courantes concernait un moyen de "traiter" les processus. fichiers une fois qu'ils ont fini de télécharger. De ce fait, nous avons créé une méthode de rappel on_file_received () déclenchée à la fin d'un téléchargement (voir numéro 79 sur notre outil de suivi des problèmes pour plus de détails).

Si vous êtes à l'aise en Python, il vous sera peut-être utile de faire fonctionner pyftpdlib en tant que serveur FTP et d'exécuter votre code de traitement à partir de la méthode de rappel. Notez que pyftpdlib est asynchrone et non multithread, votre méthode de rappel ne peut donc pas bloquer. Si vous devez exécuter des tâches de longue durée, je vous recommande d’utiliser un processus ou un thread Python distinct pour le travail de traitement proprement dit.

scroll top