online job create php mysql apache cron overlap

php - job - crontab generator



Cronjobs lentos en Cent OS 5 (7)

¿Hay alguna herramienta en Cent OS o algo que pueda hacer para asegurarme de que mi cronjob se ejecute cada hora y no superponga el siguiente?

Sí. El paquete estándar util-linux CentOS proporciona una conveniencia de línea de comandos para el bloqueo del sistema de archivos. Como suggested Digital Precision, un archivo de bloqueo es una manera fácil de sincronizar procesos.

Intenta invocar tu cronjob de la siguiente manera:

flock -n /var/tmp/stats.lock process_stats_hourly.php || logger -p cron.err ''Unable to lock stats.lock''

Deberá editar las rutas y ajustar $ PATH según corresponda. Esa invocación intentará bloquear stats.lock , generando su script de estadísticas si es exitoso, de lo contrario abandonará y registrará el error.

Alternativamente, su script podría invocar el flock() PHP para lograr el mismo efecto, pero la utilidad flock(1) ya está disponible para usted.

Tengo 1 cronjob que se ejecuta cada 60 minutos, pero por alguna razón, recientemente, se está ejecutando lentamente.

Env: centos5 + apache2 + mysql5.5 + php 5.3.3 / raid 10 / 10k HDD / 16gig ram / 4 xeon processor

Esto es lo que hace el cronjob:

  1. analizar los últimos 60 minutos de datos

    a) 1 procesa el agente de usuario de análisis y guarda los datos en la base de datos

    b) 1 proceso de impresiones parse / clics en el sitio web y guardarlos en la base de datos

  2. de los datos en el paso 1

    a) crear un pequeño informe y enviar correos electrónicos al administrador / negocio

    b) guarde el informe en una tabla diaria (disponible en la sección de administración)

Ahora veo 8 procesos (el mismo archivo) cuando ejecuto el comando ps auxf | grep process_stats_hourly.php ps auxf | grep process_stats_hourly.php (encontró este comando en stackoverflow)

Técnicamente, solo debería tener 1, no 8.

¿Hay alguna herramienta en Cent OS o algo que pueda hacer para asegurarme de que mi cronjob se ejecute cada hora y no superponga el siguiente?

Gracias


Debe usar un mecanismo de bloqueo de archivos dentro de su script process_stats_hourly.php. No tiene que ser demasiado complejo, podría tener php escribir el PID que inició el proceso en un archivo como /var/mydir/process_stats_hourly.txt. Entonces, si lleva más de una hora procesar las estadísticas y el cron inicia otra instancia del script process_stats_hourly.php, puede verificar si el archivo de bloqueo ya existe, de lo contrario no se ejecutará.

Sin embargo, le queda el problema de cómo "volver a poner en cola" el script por hora si encontró el archivo de bloqueo y no pudo iniciarse.


La salida de ps también se muestra cuando el proceso ha comenzado (vea la columna STARTED ).

$ ps auxf USER PID %CPU %MEM VSZ RSS TTY STAT STARTED TIME COMMAND root 2 0.0 0.0 0 0 ? S 18:55 0:00 [ktrheadd] ^^^^^^^ (...)

O puede personalizar el resultado:

$ ps axfo start,command STARTED COMMAND 18:55 [ktrheadd] (...)

Por lo tanto, puede estar seguro si se superponen.


Puede agregar un paso al cronjob para verificar el resultado de su comando anterior:

ps auxf | grep process_stats_hourly.php

Mantenga el bucle hasta que el comando no devuelva nada, lo que indica que el proceso no se está ejecutando, luego permita que se ejecute el código restante.


Puede usar strace -p 1234 donde 1234 es una identificación de proceso relevante, en uno de los procesos que se está ejecutando demasiado tiempo. Quizás entiendas por qué es tan lento o incluso bloqueado.


Su hardware parece ser lo suficientemente bueno para procesar esto.

1) Compruebe si ya tiene procesos pendientes. Usando el ps auxf (ver tcurvelo answer), verifica si tienes uno o más procesos que requieren demasiados recursos. Tal vez no tienes suficientes recursos para ejecutar tu cronjob.

2) Verifique sus conexiones de red: si sus bases de datos y su cronjob están en un servidor diferente, debe verificar cuál es el tiempo de respuesta entre estas dos máquinas. Tal vez tenga problemas de red que hacen que el cronjob espere a que la red le envíe el paquete.

Puede usar: Netcat , Iperf , mtr o ttcp

3) Configuración del servidor ¿Su servidor está configurado correctamente? Su sistema operativo, MySQL están configurados correctamente? Yo recomendaría leer estos artículos:

http://www3.wiredgorilla.com/content/view/220/53/

http://www.vr.org/knowledgebase/1002/Optimize-and-disable-default-CentOS-services.html

http://dev.mysql.com/doc/refman/5.1/en/starting-server.html

http://www.linux-mag.com/id/7473/

4) Verifique su base de datos: asegúrese de que su base de datos tenga los índices correctos y asegúrese de que sus consultas estén optimizadas. Lee este artículo sobre el comando de explicación

Si una consulta con pocos cientos de miles de registros tarda en ejecutarse, esto afectará al resto de su cronjob, si tiene una consulta dentro de un bucle, incluso peor.

Lee estos artículos:

http://dev.mysql.com/doc/refman/5.0/en/optimization.html

http://20bits.com/articles/10-tips-for-optimizing-mysql-queries-that-dont-suck/

http://blog.fedecarg.com/2008/06/12/10-great-articles-for-optimizing-mysql-queries/

5) ¿ Rastro y código PHP optimizado? Asegúrese de que su código PHP se ejecute lo más rápido posible.

Lee estos artículos:

http://phplens.com/lens/php-book/optimizing-debugging-php.php

http://code.google.com/speed/articles/optimizing-php.html

http://ilia.ws/archives/12-PHP-Optimization-Tricks.html

Una buena técnica para validar su cronjob es rastrear su script de cronjob: basado en su proceso de cronjob, ponga algún rastreo de depuración que incluya cuánta memoria, cuánto tiempo le tomó ejecutar el último proceso. p.ej:

<?php echo "/n-------------- DEBUG --------------/n"; echo "memory (start): " . memory_get_usage(TRUE) . "/n"; $startTime = microtime(TRUE); // some process $end = microtime(TRUE); echo "/n-------------- DEBUG --------------/n"; echo "memory after some process: " . memory_get_usage(TRUE) . "/n"; echo "executed time: " . ($end-$start) . "/n";

Al hacerlo, puede encontrar fácilmente qué proceso lleva la cantidad de memoria y cuánto tiempo lleva ejecutarlo.

6) Servidores externos / llamadas al servicio web ¿Su cronjob llama servidores externos o servicio web? si es así, asegúrese de que se carguen lo más rápido posible. Si solicita datos de un servidor externo y este servidor tarda unos segundos en devolver una respuesta que afectará la velocidad de su cronjob, especialmente si estas llamadas están en bucles.

Pruébalo y cuéntame qué encuentras.


¿Con qué frecuencia se rota ese archivo de registro?

Un trabajo de análisis de registros que de repente tarda más de lo habitual suena como que el registro no se está girando y ahora es demasiado grande para que el analizador lo maneje de manera eficiente.

Intente restablecer el archivo de registro y vea si el trabajo se ejecuta más rápido. Si eso resuelve el problema, recomiendo logrotate como un medio para prevenir el problema en el futuro.