httpstatus php http nginx amazon-web-services

php - httpstatus - http 499 nginx



NginX emite un error HTTP 499 después de 60 segundos a pesar de la configuración.(PHP y AWS) (5)

En realidad, me enfrenté al mismo problema en un servidor y me di cuenta de que después de la configuración de nginx no reinicié el servidor nginx, así que con cada hit de nginx url obtenía una respuesta http de 499. Después de reiniciar nginx, comenzó a funcionar correctamente con las respuestas http 200.

Al final de la semana pasada noté un problema en una de mis instancias de AWS medianas donde Nginx siempre devuelve una respuesta HTTP 499 si una solicitud demora más de 60 segundos. La página que se solicita es un script PHP

He pasado varios días intentando encontrar respuestas y he intentado con todo lo que puedo encontrar en Internet, incluidas varias entradas aquí en Stack Overflow, pero nada funciona.

Intenté modificar la configuración de PHP, la configuración de PHP-FPM y la configuración de Nginx. Puede ver una pregunta que planteé en los foros de Nginx el viernes ( http://forum.nginx.org/read.php?9,237692 ) aunque no ha recibido respuesta, así que espero poder encontrar un Responda aquí antes de que me obliguen a regresar a Apache, que sé que funciona.

Este no es el mismo problema que los errores HTTP 500 informados en otras entradas.

Pude replicar el problema con una nueva instancia de AWG de NginX utilizando PHP 5.4.11.

Para ayudar a cualquiera que desee ver el problema en acción, lo guiaré por la configuración que ejecuté para el último servidor de prueba Micro.

Tendrá que iniciar una nueva instancia de AWS Micro (para que sea gratis) utilizando AMI ami-c1aaabb5

Esta entrada PasteBin tiene la configuración completa para ejecutar para reflejar mi entorno de prueba. Solo tendrá que cambiar example.com dentro de la configuración de NginX al final

http://pastebin.com/WQX4AqEU

Una vez que está configurado, solo necesita crear el archivo PHP de muestra con el que estoy probando, que es

<?php sleep(70); die( ''Hello World'' ); ?>

Guárdalo en la webroot y luego prueba. Si ejecuta el script desde la línea de comando usando php o php-cgi, funcionará. Si accede a la secuencia de comandos a través de una página web y sigue el registro de acceso /var/log/nginx/example.access.log , verá que recibe la respuesta HTTP 1.1 499 después de 60 segundos.

Ahora que puede ver el tiempo de espera, revisaré algunos de los cambios de configuración que hice tanto en PHP como en NginX para tratar de evitar esto. Para PHP crearé varios archivos de configuración para que puedan ser deshabilitados fácilmente

Actualice la configuración de PHP FPM para incluir archivos de configuración externos

sudo echo '' include=/usr/local/php/php-fpm.d/*.conf '' >> /usr/local/php/etc/php-fpm.conf

Cree una nueva configuración de PHP-FPM para anular el tiempo de espera de solicitud

sudo echo ''[www] request_terminate_timeout = 120s request_slowlog_timeout = 60s slowlog = /var/log/php-fpm-slow.log '' > /usr/local/php/php-fpm.d/timeouts.conf

Cambie algunas de las configuraciones globales para garantizar que el intervalo de reinicio de emergencia sea de 2 minutos

# Create a global tweaks sudo echo ''[global] error_log = /var/log/php-fpm.log emergency_restart_threshold = 10 emergency_restart_interval = 2m process_control_timeout = 10s '' > /usr/local/php/php-fpm.d/global-tweaks.conf

A continuación, cambiaremos algunas de las configuraciones de PHP.INI, nuevamente utilizando archivos separados

# Log PHP Errors sudo echo ''[PHP] log_errors = on error_log = /var/log/php.log '' > /usr/local/php/conf.d/errors.ini sudo echo ''[PHP] post_max_size=32M upload_max_filesize=32M max_execution_time = 360 default_socket_timeout = 360 mysql.connect_timeout = 360 max_input_time = 360 '' > /usr/local/php/conf.d/filesize.ini

Como puede ver, esto está aumentando el tiempo de espera del socket a 3 minutos y ayudará a registrar errores.

Finalmente, editaré algunas de las configuraciones de NginX para aumentar el tiempo de espera de ese lado

Primero edito el archivo /etc/nginx/nginx.conf y lo agrego a la directiva http fastcgi_read_timeout 300;

A continuación, edito el archivo / etc / nginx / sites-enabled / example que creamos anteriormente (consulte la entrada pastebin) y agregue las siguientes configuraciones en la directiva del servidor

client_max_body_size 200; client_header_timeout 360; client_body_timeout 360; fastcgi_read_timeout 360; keepalive_timeout 360; proxy_ignore_client_abort on; send_timeout 360; lingering_timeout 360;

Finalmente agrego lo siguiente en la ubicación ~ .php $ sección del directorio del servidor

fastcgi_read_timeout 360; fastcgi_send_timeout 360; fastcgi_connect_timeout 1200;

Antes de volver a intentar la secuencia de comandos, inicie nginx y php-fpm para asegurarse de que la nueva configuración se haya recogido. Luego intento acceder a la página y todavía recibir la entrada HTTP / 1.1 499 dentro del NginX example.error.log.

Entonces, ¿dónde me estoy equivocando? Esto solo funciona en apache cuando establezco el tiempo máximo de ejecución de PHP en 2 minutos.

Puedo ver que la configuración de PHP se ha recogido ejecutando phpinfo () desde una página accesible a través de la web. Simplemente no lo entiendo, de hecho creo que se ha aumentado demasiado, ya que solo debería necesitar max_execution_time , default_socket_timeout de PHP modificado , así como fastcgi_read_timeout de NginX dentro de la directiva server-> location.

Actualización 1

Después de haber realizado algunas pruebas adicionales para demostrar que el problema no es que el cliente se está muriendo, he modificado el archivo de prueba para que sea

<?php file_put_contents(''/www/log.log'', ''My first data''); sleep(70); file_put_contents(''/www/log.log'',''The sleep has passed''); die(''Hello World after sleep''); ?>

Si ejecuto el script desde una página web, entonces puedo ver que el contenido del archivo se establece en la primera cadena. 60 segundos después, el error aparece en el registro de NginX. 10 segundos después, el contenido del archivo cambia a la segunda cadena, lo que demuestra que PHP está completando el proceso.

Actualización 2

Configurando fastcgi_ignore_client_abort en; cambia la respuesta de un HTTP 499 a un HTTP 200, aunque todavía no se devuelve nada al cliente final.

Actualización 3

Después de haber instalado Apache y PHP (5.3.10) en el cuadro derecho (usando apt) y luego de aumentar el tiempo de ejecución, el problema parece ocurrir también en Apache. Los síntomas son los mismos que NginX ahora, una respuesta HTTP200 pero la conexión real del cliente agota el tiempo de espera.

También comencé a notar, en los registros de NginX, que si pruebo usando Firefox, hace una solicitud doble (como este script PHP se ejecuta dos veces cuando es más largo que 60 segundos ). Aunque parece ser que el cliente solicita que el script falle


La causa del problema es Elastic Load Balancers en AWS. Ellos, por defecto, expiraron después de 60 segundos de inactividad, que es lo que estaba causando el problema.

Entonces no era NginX, PHP-FPM o PHP sino el balanceador de carga.

Para solucionar esto, simplemente vaya a la pestaña ELB "Descripción", desplácese hasta la parte inferior y haga clic en el enlace "(Editar)" junto al valor que dice "Tiempo de inactividad: 60 segundos"


Necesita encontrar en qué lugar vive el problema. No sé la respuesta exacta, pero intentemos encontrarla.

Tenemos aquí 3 elementos: nginx, php-fpm, php. Como dijiste, la misma configuración de php en apache está bien. ¿Es lo mismo sin la misma configuración? ¿Probaste apache en lugar de nginx en el mismo OS / host / etc.?

Si veremos, ese php no es sospechoso, entonces tenemos dos sospechosos: nginx y php-fpm.

Para excluir nginx: intente configurar el mismo "sistema" en ruby. Consulte https://github.com/garex/puppet-module-nginx para obtener la idea de instalar la configuración de ruby ​​más simple. O usa google (puede ser que sea aún mejor).

Mi principal sospechoso aquí es php-fpm.

Intenta jugar con estas configuraciones:

  • php-fpm`s request_terminate_timeout
  • nginx`s fastcgi_ignore_client_abort

No estoy seguro si alguien más se enfrentó a esto, pero para mí sucedió después de que puse un / al final mi url instancia. Esto dio error 499 y solo después de que quité el / , me dio 200 y todo salió bien.


Pensé que dejaría mi granito de arena. Primero el problema no está relacionado con php (aún podría estar relacionado con php, php siempre me sorprende: P). Eso es seguro. se debe principalmente a un servidor con proxy, más específicamente a nombres de nombres de host / alias, en su caso podría ser que el equilibrador de carga está solicitando nginx y nginx está devolviendo la llamada al equilibrador de carga y continúa de esa manera.

He experimentado un problema similar con nginx como equilibrador de carga y apache como servidor web / proxy