NGINX émet une erreur HTTP 499 après 60 secondes malgré la configuration. (PHP et AWS)

à la fin de la semaine dernière, j'ai remarqué un problème sur un de mes moyens AWS instances où Nginx renvoie toujours une réponse HTTP 499 si une requête prend plus de 60 secondes. La page demandée est un script PHP

j'ai passé plusieurs jours à essayer de trouver des réponses et j'ai essayé tout ce que je peux trouver sur internet y compris plusieurs entrées ici sur le débordement de pile, rien ne fonctionne.

j'ai essayé de modifier les paramètres PHP, PHP-FPM paramètres et paramètres Nginx. Vous pouvez voir une question que j'ai soulevée sur les forums NGINX vendredi ( http://forum.nginx.org/read.php?9, 237692 ) bien que cela n'ait reçu aucune réponse, j'espère donc que je pourrais trouver une réponse ici avant d'être forcé de revenir à Apache qui, je le sais, fonctionne tout simplement.

ce n'est pas le même problème que les erreurs HTTP 500 signalées dans d'autres entrées.

j'ai été capable de répliquer le problème avec une nouvelle instance micro AWS de NginX en utilisant PHP 5.4.11.

pour aider quiconque souhaite voir le problème en action, je vais vous emmener à travers la configuration que j'ai lancé pour le dernier Micro serveur de test.

vous aurez besoin de lancer une nouvelle micro instance AWS (donc c'est gratuit) en utilisant L'AMI ami-c1aaabb5

cette entrée PasteBin a la configuration complète pour fonctionner à l'image de mon environnement de test. Vous avez juste besoin d' changer example.com dans la config NginX à la fin

http://pastebin.com/WQX4AqEU

une fois que c'est configuré, vous avez juste besoin de créer l'échantillon de fichier PHP que je teste avec lequel est

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

enregistrez ça dans le webroot et faites un test. Si vous exécutez le script depuis la ligne de commande en utilisant php ou php-cgi, il fonctionnera. Si vous accédez au script via une page web et la queue du journal d'accès /var/log/nginx/exemple.accès.log , vous remarquerez que vous recevez la réponse HTTP 1.1 499 après 60 secondes.

maintenant que vous pouvez voir le timeout, je vais passer en revue certains des changements de configuration que j'ai fait à la fois PHP et NginX pour essayer de contourner cela. Pour PHP je vais créer plusieurs fichiers de configuration afin qu'ils puissent être facilement désactivés

mettre à jour la Config PHP FPM pour inclure la config externe dossiers

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

créer une nouvelle config PHP-FPM pour outrepasser le délai de la requête

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

modifier certains des réglages globaux pour s'assurer que l'intervalle de redémarrage d'urgence est de 2 minutes

# 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

ensuite, nous allons changer une partie du PHP.Paramètres INI, encore une fois en utilisant des fichiers séparés

# 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

Comme vous pouvez le voir, c'est augmenter le délai d'expiration de la socket à 3 minutes et aidera à enregistrer les erreurs.

enfin, je vais éditer certains paramètres de NginX pour augmenter le temps d'arrêt de ce côté

tout d'abord je édite le fichier /etc/nginx/nginx.conf et ajoutez ceci à la directive http fastcgi_read_timeout 300;

ensuite, je édite le fichier / etc/nginx / sites-enabled / example que nous avons créé plus tôt (voir le pastebin d'entrée) et ajouter les paramètres suivants dans le serveur directive

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;

finalement j'Ajoute ce qui suit dans le emplacement ~ .php$ section du serveur dir

fastcgi_read_timeout 360;
fastcgi_send_timeout 360;
fastcgi_connect_timeout 1200;

avant de revenir sur le script, démarrez à la fois Nginx et php-fpm pour vous assurer que les nouveaux paramètres ont été détectés. J'essaie alors d'accéder à la page et je reçois toujours L'entrée HTTP/1.1 499 dans le NginX exemple.erreur.journal.

alors, où est-ce que je vais mal? Cela fonctionne juste sur apache quand je mets le temps d'exécution maximum de PHP à 2 minutes.

je peux voir que les paramètres PHP ont été récupérés en lançant phpinfo () à partir d'une page Web accessible. Je ne comprends pas, je pense en fait que trop a été augmenté comme il devrait juste besoin de PHP max_execution_time , default_socket_timeout modifié ainsi que fastcgi_read_timeout de NginX dans la directive server->location.

mise à jour 1

ayant effectué d'autres tests pour montrer que le problème n'est pas que le client est mourant, j'ai modifié le fichier test pour qu'il soit

<?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 j'exécute le script à partir d'une page web, alors je peux voir le contenu du fichier être défini à la première chaîne. 60 secondes plus tard, l'erreur apparaît dans le journal de bord NginX. 10 secondes plus tard, le contenu du fichier change en 2nd string, prouvant que PHP termine le processus.

mise à jour 2

Réglage fastcgi_ignore_client_abort; changer la réponse à partir d'une adresse HTTP 499 HTTP 200 si rien n'est retourné au client final.

mise à jour 3

ayant installé Apache et PHP (5.3.10) sur la boîte tout droit (en utilisant apt), puis en augmentant le temps d'exécution, le problème semble aussi se produire sur Apache. Les symptômes sont les mêmes que NginX maintenant, une réponse HTTP200 mais la connexion client réelle temps avant main.

j'ai aussi commencé à remarquer, dans les journaux de NginX, que si je teste en utilisant Firefox, il fait une double requête (comme cette PHP script exécute deux fois quand plus de 60 secondes ). Bien que cela semble être le demande du client en cas de panne du script

49
demandé sur Community 2013-03-25 15:09:17

5 réponses

la cause du problème est l'équilibrage de la charge élastique sur AWS. Ils, par défaut, le temps d'arrêt après 60 secondes d'inactivité qui est ce qui causait le problème.

donc ce n'était pas NginX, PHP-FPM ou PHP mais le load balancer.

pour corriger cela, allez simplement dans L'onglet "Description" ELB, faites défiler vers le bas, et cliquez sur le lien" (Edit) "à côté de la valeur qui dit "Idle Timeout: 60 secondes"

58
répondu TFAtTheMoon 2015-11-06 18:54:51

j'ai pensé laisser mes deux cents. Tout d'abord, le problème n'est pas lié à php(il pourrait toujours être lié à php, php me surprend toujours :P ). Thats pour sûr. son principalement causé d'un serveur proxied à lui-même, plus spécifiquement nom d'hôte/alias problèmes de noms, dans votre cas, il pourrait être le équilibreur de charge demande nginx et nginx rappelle le équilibreur de charge et il continue à aller de cette façon.

j'ai connu un similaires problème avec nginx comme balancier de charge et apache comme serveur web /proxy

1
répondu Waheed 2017-04-16 07:21:50

vous devez trouver dans quel endroit vivent les problèmes. Je ne connais pas la réponse exacte, mais essayons de la trouver.

nous avons ici 3 éléments: nginx, php-fpm, php. Comme vous l'avez dit, les mêmes paramètres php sous apache sont corrects. Ne c'est même pas la même configuration? Avez-vous essayé apache au lieu de nginx sur le même OS/host/etc.?

si nous voyons que php n'est pas suspect, alors nous avons deux suspects: nginx & php-fpm.

pour exclure nginx: essayer de installer le même "système" sur ruby. Voir https://github.com/garex/puppet-module-nginx pour obtenir l'idée d'installer Ruby setup le plus simple. Ou utilisez google (peut-être il sera encore mieux).

mon principal suspect est php-fpm.

essayez de jouer avec ces paramètres:

  • php-fmp's request_terminate_timeout
  • nginx est fastcgi_ignore_client_abort
0
répondu gaRex 2013-03-25 14:18:58

en fait, j'ai fait face au même problème sur un serveur et j'ai compris qu'après les changements de configuration de nginx, Je n'ai pas redémarré le serveur nginx, donc avec chaque succès d'url NGINX, je recevais une réponse http 499. Après le redémarrage de nginx, il a commencé à fonctionner correctement avec les réponses http 200.

0
répondu Rajeev kumar 2016-10-18 12:48:28

pas sûr si quelqu'un d'autre a fait face à cela mais pour moi, il est arrivé après que j'ai mis un / à la fin de mon url d'instance.Cela a donné 499 erreur et seulement après que j'ai enlevé le / , il m'a donné 200 et tout est allé bien.

0
répondu Souvik Ray 2018-04-04 07:24:11