2008-10-16 6 views
0

La situation est la suivante:fichiers texte Process ftp'ed dans un ensemble de répertoires dans un serveur hébergé

Une série de postes de travail à distance de recueillir des données sur le terrain et ftp les données recueillies sur le terrain à 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 provoque l'écrasement des données précédentes. Nous aimerions en quelque sorte 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 un cronjob sur le serveur FTP, mais il existe une restriction sur les Conditions d'utilisation pour autoriser uniquement les cronjobs à intervalles de 30 minutes, car il s'agit d'un hébergement partagé. Compte tenu du nombre de postes de travail téléchargés et de l'intervalle de 10 minutes entre les envois, il semble que la limite de 30 minutes entre les appels du cronjob puisse poser problème.

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

La mise à niveau vers un serveur dédié peut être nécessaire, mais j'aimerais quand même obtenir des informations sur la façon de résoudre ce problème de la manière la plus élégante.

Répondre

4

La plupart des Linux modernes prendront en charge inotify pour informer votre processus lorsque le contenu d'un répertoire a changé, vous n'avez donc même pas besoin d'interroger.

Edit: En ce qui concerne le commentaire ci-dessous de Mark Baker.

« Attention cependant, comme vous serez informé dès que le fichier est créé, pas quand il est fermé donc vous aurez besoin d'un façon de s'assurer que vous ne prenez pas de fichiers partiels. " Cela se produira avec la montre inotify que vous avez définie au niveau du répertoire - la façon de vous assurer que vous ne récupérez pas le fichier partiel est de définir une autre surveillance inotify sur le nouveau fichier et de rechercher l'événement IN_CLOSE afin que vous sachiez que le fichier a été complètement écrit. Une fois que votre processus a vu cela, vous pouvez supprimer la montre inotify sur ce nouveau fichier, et le traiter à votre guise.

4

Vous pourriez envisager un démon persistant qui maintient l'interrogation des répertoires cibles:

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

Ensuite, votre tâche cron peut juste essayer de démarrer le démon toutes les 30 minutes. Si le démon ne peut pas récupérer le fichier de verrouillage, il meurt simplement, donc il n'y a pas de souci pour l'exécution de plusieurs démons.

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

1

La limite de 30 minutes est vraiment stupide. Démarrer des processus sous linux n'est pas une opération coûteuse, donc si tout ce que vous faites est de rechercher de nouveaux fichiers, il n'y a pas de bonne raison de ne pas le faire plus souvent que cela. Nous avons des tâches cron qui s'exécutent toutes les minutes et n'ont aucun effet notable sur les performances. Cependant, je réalise que ce n'est pas votre règle et si vous allez rester avec ce fournisseur d'hébergement, vous n'avez pas le choix.

Vous aurez besoin d'un démon de longue durée quelconque. Le moyen le plus simple est d'interroger régulièrement, 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 depuis perl avec Linux :: Inotify, ou depuis python avec pyinotify.

Soyez prudent, car vous serez averti dès la création du fichier et non lorsqu'il sera fermé. Vous aurez donc besoin d'un moyen de vous assurer que vous ne récupérez pas les fichiers partiels. Avec l'interrogation, il est peu probable que vous voyiez des fichiers partiels, mais cela arrivera éventuellement et sera un mauvais bug difficile à reproduire quand cela arrivera, alors mieux vaut traiter le problème maintenant.

1

Si vous souhaitez conserver votre configuration de serveur FTP existante, je vous conseille d'utiliser un processus inotify ou démonisé pour regarder les répertoires de téléchargement. Si vous êtes d'accord pour passer à un serveur FTP différent, vous pouvez jeter un oeil à pyftpdlib qui est une librairie serveur Python FTP.

J'ai fait partie de l'équipe de développement pour pyftpdlib un moment et l'une des demandes les plus courantes était de pouvoir "traiter" les fichiers une fois qu'ils ont terminé le téléchargement. Pour cette raison, nous avons créé une méthode de rappel on_file_received() qui est déclenchée à la fin d'un téléchargement (voir issue #79 sur notre outil de suivi des problèmes pour plus de détails). Si vous êtes à l'aise avec Python, il est possible que vous utilisiez pyftpdlib comme serveur FTP et que vous exécutiez votre code de traitement à partir de la méthode de rappel. Notez que pyftpdlib est asynchrone et non multi-thread, de sorte que votre méthode de rappel ne peut pas bloquer. Si vous devez exécuter des tâches de longue durée, je recommanderais un processus ou un thread Python séparé pour le travail de traitement.

Questions connexes