206 votes

Raison possible des codes d'erreur NGINX 499

Je reçois beaucoup de codes d'erreur NGINX 499. Je vois que c'est un problème côté client. Ce n'est pas un problème avec NGINX ou ma pile uWSGI. Je note la corrélation dans les journaux uWSGI lorsqu'un code 499 est obtenu.

address space usage: 383692800 bytes/365MB} {rss usage: 167038976
bytes/159MB} [pid: 16614|app: 0|req: 74184/222373] 74.125.191.16 ()
{36 vars in 481 bytes} [Fri Oct 19 10:07:07 2012] POST /bidder/ =>
generated 0 bytes in 8 msecs (HTTP/1.1 200) 1 headers in 59 bytes (1
switches on core 1760)
SIGPIPE: writing to a closed pipe/socket/fd (probably the client
disconnected) on request /bidder/ (ip 74.125.xxx.xxx) !!!
Fri Oct 19 10:07:07 2012 - write(): Broken pipe [proto/uwsgi.c line
143] during POST /bidder/ (74.125.xxx.xxx)
IOError: write error

Je cherche une explication plus approfondie et j'espère qu'il n'y a pas de problème avec ma configuration NGINX pour uwsgi. Je le prends au pied de la lettre. Cela semble être un problème de client.

259voto

mrbo Points 241

HTTP 499 dans Nginx signifie que l'option le client a fermé la connexion avant que le serveur ne réponde à la demande. D'après mon expérience, cela est généralement dû à délai d'attente côté client . Comme je le sais, c'est un code d'erreur spécifique à Nginx.

107voto

Mads Skjern Points 2254

Dans mon cas, j'étais impatient et j'ai fini par mal interpréter le journal.

En fait, le vrai problème était la communication entre nginx et uwsgi, et non entre le navigateur et nginx. Si j'avais chargé le site dans mon navigateur et que j'avais attendu assez longtemps, j'aurais obtenu un "504 - Bad Gateway". Mais cela a pris tellement de temps que j'ai continué à essayer des trucs, puis à rafraîchir dans le navigateur. Je n'ai donc jamais attendu assez longtemps pour voir l'erreur 504. Lors de l'actualisation dans le navigateur, la demande précédente est fermée et Nginx l'écrit dans le journal sous la forme 499.

Élaboration

Je supposerai ici que le lecteur en sait aussi peu que moi lorsque j'ai commencé à jouer.

Ma configuration comprenait un proxy inverse, le serveur nginx, et un serveur d'applications, le serveur uWSGI, derrière lui. Toutes les demandes du client allaient au serveur nginx, puis étaient transmises au serveur uWSGI, et la réponse était renvoyée de la même manière. Je pense que c'est ainsi que tout le monde utilise nginx/uwsgi et est censé l'utiliser.

Mon nginx fonctionnait comme il le devait, mais quelque chose clochait avec le serveur uwsgi. Il y a deux façons (peut-être plus) dont le serveur uwsgi peut ne pas répondre au serveur nginx.

1) uWSGI dit, "Je suis en train de traiter, attendez et vous obtiendrez bientôt une réponse". nginx a une certaine période de temps, qu'il est prêt à attendre, fx 20 secondes. Après cela, il répondra au client avec une erreur 504.

2) uWSGI est mort, ou uWSGI meurt alors que nginx l'attend. nginx le voit tout de suite et dans ce cas, il renvoie une erreur 499.

Je testais ma configuration en faisant des requêtes dans le client (navigateur). Dans le navigateur, rien ne se passait, tout restait en suspens. Après environ 10 secondes (moins que le délai d'attente), j'ai conclu que quelque chose n'allait pas (ce qui était vrai) et j'ai fermé le serveur uWSGI à partir de la ligne de commande. Ensuite, je me suis rendu dans les paramètres uWSGI, j'ai essayé quelque chose de nouveau, puis j'ai redémarré le serveur uWSGI. Dès que je fermais le serveur uWSGI, le serveur nginx renvoyait une erreur 499.

J'ai donc continué à déboguer avec l'erreur 499, ce qui signifie que je dois chercher l'erreur 499 sur Google. Mais si j'avais attendu assez longtemps, j'aurais eu l'erreur 504. Si j'avais obtenu l'erreur 504, j'aurais été en mesure de mieux comprendre le problème, puis de déboguer.

La conclusion est donc que le problème venait de l'uWGSI, qui restait en suspens ("Attendez un peu plus longtemps, juste un peu plus longtemps, puis j'aurai une réponse pour vous...").

Comment j'ai réparé que problème, je ne me souviens pas. Je suppose que ça peut être causé par beaucoup de choses.

44voto

mrki Points 1261

Le "client" dans "le client a fermé la connexion" n'est pas nécessairement le navigateur Web !

Vous pouvez trouver des erreurs 499 dans un fichier journal Nginx si vous avez un service d'équilibrage de charge entre vos utilisateurs et votre Nginx -- en utilisant AWS ou haproxy . Dans cette configuration, le service d'équilibrage de charge agira comme un client pour le serveur Nginx et comme un serveur pour le navigateur Web, en envoyant les données par proxy dans les deux sens.

Para haproxy les valeurs par défaut de certains délais applicables sont d'environ 60 secondes pour la connexion à l'amont et pour la lecture de l'amont (Nginx) ou de l'aval (navigateur Web).

Cela signifie que si, après 60 secondes, le proxy ne s'est pas connecté à l'amont pour écrire, ou s'il n'a pas reçu de données de l'aval (navigateur Web) ou de l'amont (Nginx) dans le cadre d'une demande ou d'une réponse HTTP, respectivement, il fermera la connexion correspondante, ce qui sera traité comme une erreur par Nginx, du moins, si ce dernier a traité la demande à ce moment-là (en prenant trop de temps).

Les délais d'attente peuvent survenir pour des sites Web très fréquentés ou des scripts qui ont besoin de plus de temps pour être exécutés. Vous devrez peut-être trouver une valeur de timeout qui vous conviendra. Par exemple en l'étendant à un nombre plus grand, comme 180 secondes. Cela pourrait régler le problème pour vous.

En fonction de votre configuration, vous pouvez voir un 504 Gateway Timeout Une erreur HTTP dans votre navigateur qui peut indiquer que quelque chose ne va pas avec php-fpm. Ce ne sera pas le cas, cependant, avec 499 erreurs dans vos fichiers journaux.

23voto

bartomeu Points 366

Comme vous le soulignez 499 un avortement de connexion enregistré par le nginx. Mais généralement, cela se produit lorsque votre serveur dorsal est trop lent. et qu'un autre proxy expire en premier ou que le logiciel de l'utilisateur interrompt la connexion. Vérifiez donc si uWSGI répond rapidement ou non et s'il y a une charge sur uWSGI / serveur de base de données.

Dans de nombreux cas, il y a d'autres proxies entre l'utilisateur et nginx. Certains peuvent se trouver dans votre infrastructure, comme un CDN, un équilibreur de charge, un cache Varnish, etc. D'autres peuvent être du côté de l'utilisateur, comme un proxy de mise en cache, etc.

S'il y a des proxies de votre côté, comme un équilibreur de charge / CDN ... vous devez définir les délais d'attente pour que votre backend soit le premier à être mis hors service, puis progressivement les autres proxies pour l'utilisateur.

Si vous avez :

user >>> CDN >>> Load Balancer >>> Nginx >>> uWSGI

Je vous recommanderai à Seth :

  • n secondes pour le délai d'attente de uWSGI
  • n+1 secondes pour le délai d'attente de nginx
  • n+2 senconds to timeout to Load Balancer (délai d'attente pour l'équilibreur de charge)
  • n+3 secondes de délai d'attente pour le CDN.

Si vous ne pouvez pas régler certains délais (comme le CDN), trouvez quel est son délai d'attente et ajustez les autres en fonction de celui-ci ( n , n-1 ...).

Cela fournit une chaîne correcte de délais d'attente. et vous trouverez vraiment dont donner le délai d'attente et retourner le bon code de réponse à l'utilisateur.

22voto

rogerdpack Points 12806

Il s'avère que 499 veut vraiment dire "connexion client interrompue".

J'avais un paramètre de "délai de lecture" client de 60s (et nginx a également un proxy_read_timeout par défaut de 60s). Ce qui se passait dans mon cas, c'est que nginx envoyait un message d'erreur dans le fichier error.log. upstream timed out (110: Connection timed out) while reading upstream et ensuite nginx essaie à nouveau "le prochain serveur proxy dans le groupe de serveurs backend que vous avez configuré". C'est si vous en avez plus d'un.

Ensuite, il essaie le suivant et le suivant jusqu'à (par par défaut ), il les a tous épuisés. Au fur et à mesure que chacun d'eux s'épuise, il les supprime également de la liste des serveurs dorsaux "actifs". Une fois que tous les serveurs ont été épuisés, il renvoie un 504 gateway timeout.

Ainsi, dans mon cas, nginx a marqué le serveur comme "indisponible", a réessayé sur le serveur suivant, puis le serveur de mon client 60s timeout (immédiatement) s'est produit, donc je verrais un upstream timed out (110: Connection timed out) while reading upstream suivi immédiatement d'un journal de 499. Mais c'était juste une coïncidence de timing.

En rapport :

Si tous les serveurs du groupe sont marqués comme étant actuellement indisponibles, il renvoie un message de type 502 Bad Gateway. pour 10s également. Voir aquí max_fails et fail_timeout. Dans les journaux, on peut lire no live upstreams while connecting to upstream.

Si vous n'avez qu'un seul backend proxy dans votre groupe de serveurs, il essaye simplement ce serveur et renvoie un 504 Gateway Time-out et ne supprime pas le serveur unique de la liste des serveurs "live", si proxy_read_timeout est dépassée. Voir aquí "S'il n'y a qu'un seul serveur dans un groupe, les paramètres max_fails, fail_timeout et slow_start sont ignorés, et un tel serveur ne sera jamais considéré comme indisponible."

La partie vraiment délicate est que si vous spécifiez proxy_pass à "localhost" et que votre boîte a aussi des "versions de localhost" ipv6 et ipv4 sur elle en même temps (la plupart des boîtes le font par défaut), cela comptera comme si vous aviez une "liste" de plusieurs serveurs dans votre groupe de serveurs, ce qui signifie que vous pouvez vous retrouver dans la situation ci-dessus où il retourne "502 pour 10s" même si vous ne listez que un serveur . Voir aquí "Si un nom de domaine se résout à plusieurs adresses, elles seront toutes utilisées à la ronde". Une solution de contournement consiste à le déclarer comme proxy_pass http://127.0.0.1:5001; (son adresse ipv4) à éviter c'est à la fois ipv6 et ipv4. Dans ce cas, cela compte comme un comportement de "serveur unique".

Il y a quelques paramètres différents que vous pouvez modifier pour rendre ce problème moins important. Par exemple, augmenter les délais d'attente ou faire en sorte que les serveurs ne soient pas marqués comme "désactivés" lorsqu'ils dépassent le délai d'attente... ou encore corriger la liste pour qu'elle ne soit que de taille 1, voir ci-dessus :)

Voir aussi : https://serverfault.com/a/783624/27813

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X