Pregunta

La situación es la siguiente:

Una serie de estaciones de trabajo remotas recopilan datos de campo y transfieren los datos de campo recopilados a un servidor a través de ftp. Los datos se envían como un archivo CSV que se almacena en un directorio único para cada estación de trabajo en el servidor FTP.

Cada estación de trabajo envía una nueva actualización cada 10 minutos, lo que hace que los datos anteriores se sobrescriban. Nos gustaría de alguna manera concatenar o almacenar estos datos automáticamente. El procesamiento de la estación de trabajo es limitado y no puede extenderse, ya que es un sistema integrado.

Una sugerencia ofrecida fue ejecutar un cronjob en el servidor FTP, sin embargo, hay una restricción en los Términos de servicio para permitir solo los cronjobs en intervalos de 30 minutos, ya que es un alojamiento compartido. Dada la cantidad de estaciones de trabajo que se cargan y el intervalo de 10 minutos entre cada carga, parece que el límite de 30 minutos entre las llamadas del cronjob podría ser un problema.

¿Hay algún otro enfoque que pueda sugerirse? Los lenguajes de script del lado del servidor disponibles son perl, php y python.

La actualización a un servidor dedicado puede ser necesaria, pero todavía me gustaría recibir información sobre cómo resolver este problema de la manera más elegante.

¿Fue útil?

Solución

La mayoría de los Linux modernos admitirán inotify para que su proceso sepa cuándo ha cambiado el contenido de un directorio, por lo que ni siquiera necesita realizar una encuesta.

Editar: con respecto al comentario de Mark Baker a continuación:

" Sin embargo, tenga cuidado, ya que se le notificará tan pronto como se cree el archivo, no cuando se cierre. Por lo tanto, necesitará alguna forma de asegurarse de no recoger archivos parciales. & Quot;

Eso sucederá con el reloj inotify que configuró en el nivel del directorio. La manera de asegurarse de que no retire el archivo parcial es establecer un nuevo reloj inotify en el nuevo archivo y buscar el evento IN_CLOSE. que sabe que el archivo se ha escrito completamente.

Una vez que su proceso haya visto esto, puede eliminar la vigilancia de inotificación en este nuevo archivo y procesarlo a su gusto.

Otros consejos

Puede considerar un demonio persistente que sigue sondeando los directorios de destino:

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

Luego, tu tarea cron puede intentar iniciar el daemon cada 30 minutos. Si el demonio no puede agarrar el archivo de bloqueo, simplemente muere, por lo que no hay que preocuparse por la ejecución de múltiples demonios.

Otro enfoque a considerar sería enviar los archivos a través de HTTP POST y luego procesarlos a través de un CGI. De esta forma, garantiza que se hayan resuelto correctamente en el momento de la presentación.

El límite de 30 minutos es bastante tonto realmente. Iniciar procesos en Linux no es una operación costosa, por lo tanto, si todo lo que está haciendo es buscar nuevos archivos, no hay una buena razón para no hacerlo más a menudo. Tenemos trabajos cron que se ejecutan cada minuto y no tienen ningún efecto notable en el rendimiento. Sin embargo, me doy cuenta de que no es su regla y si va a seguir con ese proveedor de alojamiento, no tiene otra opción.

Necesitarás un demonio de larga duración de algún tipo. La forma más fácil es hacer una encuesta regularmente, y probablemente eso es lo que yo haría. Inotify, por lo que recibe una notificación tan pronto como se crea un archivo, es una mejor opción.

Puedes usar inotify desde perl con Linux :: Inotify, o desde python con pyinotify.

Sin embargo, tenga cuidado, ya que se le notificará tan pronto como se cree el archivo, no cuando se cierre. Así que necesitarás alguna forma de asegurarte de no recoger archivos parciales.

Con el sondeo es menos probable que veas archivos parciales, pero ocurrirá con el tiempo y será un error desagradable difícil de reproducir cuando ocurra, por lo que es mejor tratar el problema ahora.

Si desea permanecer con la configuración de su servidor FTP existente, le recomiendo que utilice un proceso de inotificación o demonio para ver los directorios de carga. Si está de acuerdo con cambiarse a un servidor FTP diferente, puede consultar pyftpdlib que es una versión del servidor FTP de Python.

He sido parte del equipo de desarrollo de pyftpdlib por un tiempo y una de las solicitudes más comunes fue una forma de " proceso " archivos una vez que han terminado de subir. Debido a eso, creamos un método de devolución de llamada on_file_received () que se activa al completar una carga (consulte problema # 79 en nuestro rastreador de problemas para más detalles).

Si se siente cómodo en Python, podría funcionar bien si ejecuta Pyftpdlib como su servidor FTP y ejecute su código de procesamiento desde el método de devolución de llamada. Tenga en cuenta que pyftpdlib es asíncrono y no multiproceso, por lo que su método de devolución de llamada no puede estar bloqueando. Si necesita ejecutar tareas de larga duración, recomendaría que se use un proceso o hilo de Python separado para el trabajo de procesamiento real.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top