2012-03-01 14 views
5

tengo una tarea programada en PHP que está fallando después de correr durante 29 minutos. El error en el registro (/var/log/php_errors.log) es:PHP trabajo cron terminación prematura debido al tiempo máximo de ejecución error grave

[01-Mar-2012 00:32:57 UTC] PHP Fatal error: Maximum execution time of 60 seconds exceeded in /path/file.php on line 2079 

la entrada de crontab que desencadena el Cron es:

00 00 * * * /usr/bin/php /path/file.php 

De mi investigación no creo que esto está relacionado con el ajuste de configuración porque max_execution_time :

  1. Sé de hecho que funcionó durante 29:18 minutos (es decir, mucho más de 60 como el mensaje de error).
  2. De the PHP docs - Cuando se ejecuta PHP desde la línea de comandos de la configuración por defecto es 0.

Q: ¿Por qué está terminando temprano el guión?


Notas:

El guión es muy pesado, y se ejecuta muchos miles de consultas de base de datos, pero yo estaba corriendo top y la carga de la CPU no era alto.

La línea desde el registro de errores es una llamada mysql_query:

$sql = "SELECT SUM(amount) FROM mytab WHERE mem = '$id' AND validto > '$now'"; 
$res = mysql_query($sql); 

> php -v 
PHP 5.3.10 (cli) (built: Feb 2 2012 17:34:38) 
Copyright (c) 1997-2012 The PHP Group 
Zend Engine v2.3.0, Copyright (c) 1998-2012 Zend Technologies 
    with Suhosin v0.9.33, Copyright (c) 2007-2012, by SektionEins GmbH 

> cat /etc/redhat-release 
Red Hat Enterprise Linux Server release 5.7 (Tikanga) 

actualización - descubrí por qué la secuencia de comandos puede funcionar durante 29 minutos de tiempo real, pero PHP puede salir citando el tiempo de ejecución mucho más bajo.

Cualquier tiempo dedicado a actividades que ocurran fuera de la ejecución del script como llamadas al sistema usando system(), operaciones de flujo, consultas de bases de datos, etc. no se incluye al determinar el tiempo máximo que el script se ha estado ejecutando .

(de the set_time_limit() docs, pero también se menciona en the max-execution-time docs). Esto fue relevante para mí porque la mayor parte del script llevaba mucho tiempo ejecutando consultas db y llamadas a la API de pago que no habrían estado cronometrando el tiempo de ejecución.

+1

el trabajo cron no tiene nada que ver con su error, este es un problema puro de PHP. verifique si hay pérdidas de memoria, intente desarmar algunas de las matrices de fallas después de ejecutar los bucles. libere otras grandes variables entre consultas. –

+0

También notará en la documentación que dice: _el tiempo máximo de ejecución no se ve afectado por llamadas al sistema, operaciones de flujo, etc._. ¿Puedes asegurarte de que es de hecho el PHP _CLI_ que dispara el cron? –

+0

También verificaría que tenga índices adecuados para acelerar la selección. ¿Tienes un índice de *** mem *** y *** validto ***? –

Respuesta

1

Si obtiene PHP Fatal error: Maximum execution time of 60 seconds exceeded entonces seguro algunos pieza de ejecutar código PHP se ejecuta comunicado set_time_limit(60) en alguna parte. El modo CLI de PHP puede establecerse como predeterminado sin límite de tiempo, pero si cualquier ruta de código alguna vez establece el límite de tiempo, se cumplirá. La razón por la que PHP se ejecutó durante media hora es porque set_time_limit establece el límite para el tiempo de CPU y si el proceso es E/S limitado o espera otros procesos, el uso total de CPU alcanzaría la marca de 60 segundos mucho más tarde en tiempo real .

Intente buscar todo su código fuente para set_time_limit. Si no encuentra nada, agregue set_time_limit(0) al comienzo del script para asegurarse de que el límite de 60 segundos no provenga del archivo de configuración modificado localmente. Por ejemplo, en Ubuntu LTS, la configuración CLI de PHP se define en /etc/php5/cli/php.ini.

+0

GRACIAS. Información útil. grepping para 'set_time_limit' reveló el problema. – Tom

2

Bueno, se puede establecer un valor mayor que el límite de tiempo, o se puede establecer ilimitada utilizando set-time-limit():

<?php set_time_limit(0); ?> 

pero Acctually Puedo utilizar esto también en el inicio de la secuencia de comandos

ignore_user_abort(1); 
1

Lamentablemente no puedo escribir un comentario, por lo que mi pregunta sería ¿qué ocurre si lo ejecuta manualmente? ¿También se agotará el tiempo de espera?

Si no se agota el tiempo cuando lo ejecuta manualmente, le sugiero que llame a un pequeño script de shell, que en realidad ejecuta un shell y ejecuta "/ usr/bin/php /path/file.php" dentro del cáscara.

00 00 * * * /usr/local/scripts/start_php_job.sh

File: /usr/local/scripts/start_php_job.sh 
#!/usr/bin/bash 
date 

/usr/local/bin/php /path/to/script 

date 
+0

Gracias. Intenté ejecutarlo manualmente desde la línea de comandos y obtuve el mismo error que cuando se activó automáticamente a través de cron. – Tom

+1

¿Puede registrar el consumo de memoria durante la ejecución? ¿Cuáles son sus "límites de recursos (ulimit -a)? Supongo que si se detiene así, la memoria caché del búfer está llena para el uso máximo de mem del usuario, el uso máximo de mem de sql-server o simplemente el límite máximo del sistema alcanza el máximo. Te sugiero que hagas un ps -uef (creo que este es el que también muestra la memoria) y grep tu proceso, hazlo cada 5 segundos. Lo que también sería bueno si el código * return * realmente es. Si lo ejecutas en un shellscript como se describe arriba puede obtener el código de error por echo $ y se mostrará, tal vez eso le da más pistas. –

Cuestiones relacionadas