Evite tiempos de espera con nginx y php-fpm

Estoy experimentando tiempos de espera cuando ejecuto un detector de cola de trabajos (bucle while infinito). El oyente llama a un trabajador cuya función consiste en ejecutar un software PhantomJS usando shell_exec().

Estoy ejecutando nginx 1.2.7 con php5-fpm y PHP framework Laravel 4 (que usa componentes de Symfony).

Problema: Después de ejecutarse por un tiempo, el oyente se cerrará con el error The process timed out. Sospecho que se debe a la shell_exec() que tarda mucho tiempo en devolver sus resultados.

enter image description here

Intentos: Intenté aumentar la configuración de tiempos de espera en nginx a 600 segundos, pero eso no ayudó. set_time_limit(0) tampoco ayuda.

¿Cómo puede evitar que se agote el tiempo de espera, o al menos evitar que el error de tiempo de espera acabe con el oyente de la cola?

sitios habilitados / misitio.com

server {
    listen   80;
    server_name www.mysite.com mysite.com *.mysite.com;
    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;
    root /var/www/mysite/public;

    index index.php index.html;

    location / {
        try_files $uri $uri/ /index.php?$args ;
    }
    location ~ \.php$ {
        fastcgi_pass unix:/var/run/php5-fpm.sock;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_read_timeout 600;
        fastcgi_send_timeout 600;
        client_body_timeout 600;
        send_timeout 600;
        proxy_read_timeout 600;
    }

}

Seguimiento de pila de errores

exception 'Symfony\Component\Process\Exception\RuntimeException' with message 'The process timed out.' in /var/www/mysite/vendor/symfony/process/Symfony/Component/Process/Process.php:413
Stack trace:
#0 /var/www/mysite/vendor/symfony/process/Symfony/Component/Process/Process.php(201): Symfony\Component\Process\Process->wait(NULL)
#1 /var/www/mysite/vendor/laravel/framework/src/Illuminate/Queue/Listener.php(63): Symfony\Component\Process\Process->run()
#2 /var/www/mysite/vendor/laravel/framework/src/Illuminate/Queue/Listener.php(50): Illuminate\Queue\Listener->runProcess(Object(Symfony\Component\Process\Process), 128)
#3 /var/www/mysite/vendor/laravel/framework/src/Illuminate/Queue/Console/ListenCommand.php(69): Illuminate\Queue\Listener->listen(NULL, 'default', 0, 128, 60)
#4 /var/www/mysite/vendor/laravel/framework/src/Illuminate/Console/Command.php(108): Illuminate\Queue\Console\ListenCommand->fire()
#5 /var/www/mysite/vendor/symfony/console/Symfony/Component/Console/Command/Command.php(240): Illuminate\Console\Command->execute(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#6 /var/www/mysite/vendor/laravel/framework/src/Illuminate/Console/Command.php(96): Symfony\Component\Console\Command\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#7 /var/www/mysite/vendor/symfony/console/Symfony/Component/Console/Application.php(193): Illuminate\Console\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#8 /var/www/mysite/vendor/symfony/console/Symfony/Component/Console/Application.php(106): Symfony\Component\Console\Application->doRun(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#9 /var/www/mysite/artisan(59): Symfony\Component\Console\Application->run()
#10 {main}

Actualizaciones

Todavía se producen tiempos de espera cuando se utiliza Apache 2.2.22 y la configuración predeterminada. ¿Alguna idea de qué configuraciones se pueden cambiar para evitar los tiempos de espera?

preguntado el 16 de abril de 13 a las 08:04

¿Puedes ejecutar este script sin nginx? -

@Victor Sí, estoy ejecutando la secuencia de comandos en apache 2.2.22 en lugar de nginx 1.2.7 y todavía se producen tiempos de espera. Apache se está ejecutando con la configuración predeterminada. ¿Algunas ideas? -

No estoy tratando de usar tiempos de espera en nginx. Pero creo que se puede conectar con el tipo php ejecutándose en nginx. En ese uso, php cargado en la memoria y ejecutando más de 1 solicitud y no descargado después de cada solicitud. No se puede guardar el tiempo de espera de uso porque puede llevar a obtener muchos recursos del sistema. Pero es mi IMHO. Cuando hablé de "sin nginx", pensé en ejecutar su script en la línea de comandos o en cron. ¿Puedes ejecutar un script sin ningún servidor web? -

@Victor puedo ejecutar usando PHP sin ningún servidor web, por ejemplo: php artisan queue:work ejecutará el script una vez. Pero el tiempo de espera se produce una vez cada 1000-2000 ejecuciones, por lo que nunca he probado mil veces manualmente para ver si todavía tiene tiempos de espera.

2 Respuestas

Verifique #3. Esa llamada de función tiene un 60 muy sospechoso como argumento. ¿Está seguro de que está alcanzando el límite de php o el código está escuchando la salida de la consola durante un máximo de 60 segundos?

Respondido 17 Abr '13, 20:04

Refiriéndose a github.com/laravel/framework/blob/master/src/Illuminate/Queue/…, ese es el tiempo de espera predeterminado (impuesto por el oyente de Queue) pero no estoy seguro de lo que significa... - nyxynyx

Una vez que la listen proceso ocupa demasiada memoria, se mata a sí mismo.

if ($this->memoryExceeded($memory))
{
    $this->stop(); return;
}

Escuché que se supone que debes usar Supervisor para garantizar que el proceso se reinicie y siempre se ejecute. Sin embargo, no estoy seguro de por qué tienes que hacer esto /: y aún no lo he probado.

Respondido 22 Abr '13, 21:04

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.