web-dev-qa-db-fra.com

Nginx uwsgi (104: connexion réinitialisée par un homologue) lors de la lecture de l'en-tête de réponse depuis l'amont

L’environnement est Nginx + uwsgi.

Obtention d'une erreur de passerelle 502 incorrecte de Nginx sur certaines demandes GET. Semble être lié à la longueur de l'URL. Dans notre cas particulier, il s’agissait d’une longue liste de paramètres GET. Raccourcissez les paramètres GET sans erreur 502.

À partir de nginx/error.log

[error] 22113#0: *1 recv() failed (104: Connection reset by peer) while reading response header from upstream, client: 192.168.1.100, server: server.domain.com, request: "GET <long_url_here>"

Aucune information dans le journal des erreurs uwsgi.

39
user3470130

Après avoir passé beaucoup de temps là-dessus, j'ai finalement compris. Il existe de nombreuses références à Nginx et à la réinitialisation de la connexion par les pairs. La plupart d'entre eux semblaient être liés à PHP. Je n'ai pas trouvé de réponse spécifique à Nginx et à uwsgi.

J'ai finalement trouvé une référence à fastcgi et une erreur de passerelle incorrecte 502 ( https://support.plesk.com/hc/en-us/articles/213903705 ). Cela m’a amené à rechercher une limite de taille de tampon dans la configuration uwsgi qui existe sous la forme buffer-size . La valeur par défaut est 4096. Dans la documentation, il est indiqué:

Si vous prévoyez de recevoir de grandes requêtes avec de nombreux en-têtes, vous pouvez augmenter cette valeur jusqu'à 64 000 (65 535).

Il y a beaucoup de façons de configurer uwsgi, il m'est arrivé d'utiliser un fichier .ini. Donc, dans mon fichier .ini, j'ai essayé:

buffer-size=65535

Cela a résolu le problème. Vous pouvez ajuster cela au goût. Vous pouvez peut-être commencer par le maximum et revenir en arrière jusqu'à obtenir une valeur acceptable, ou simplement le laisser au maximum.

C'était frustrant de retrouver, car il n'y avait pas d'erreur du côté uwsgi.

74
user3470130

Je recevais la même erreur nginx et il n’y avait aucune information dans le journal uwsgi. Le problème était que, dans certains cas, l'application ne consommait pas tout le corps de la demande, comme indiqué dans http://uwsgi-docs.readthedocs.org/en/latest/ThingsToKnow.html :

Si une demande HTTP a un corps (comme une demande POST générée par un formulaire), vous devez le lire (le consommer) dans votre application. Si vous ne le faites pas, le socket de communication avec votre serveur Web risque d'être endommagé. Si vous êtes paresseux, vous pouvez utiliser l'option post-mise en mémoire tampon qui lira automatiquement les données pour vous. Pour les applications en rack, cela est automatiquement activé.

Bien sûr, ce n'est pas un problème dans votre cas, mais cela peut être utile pour les autres personnes qui obtiennent la même erreur nginx.

3
Rinas

Merci, la même solution est adoptée dans le cas d'un serveur PHP. Nous devons simplement augmenter la valeur de l'attribut "output_buffering", dans php.ini, à une valeur supérieure telle que 65535 ou à une autre valeur appropriée.

3
Eduan Lenine

Lorsque nous recevons un message tel que (104: Connection reset by peer) while reading response header from upstream, le plus souvent, nous pourrions blâmer le côté amont de ce type d'erreur.

Comme décrit, la connexion a été réinitialisée par l'homologue en amont, pas par nginx lui-même. Nginx en tant que client peut à peine faire quoi que ce soit pour y remédier.

Je soupçonne que la modification de la taille de la mémoire tampon fera l'affaire. En gros, la commande modifie la taille de la mémoire tampon dans laquelle les en-têtes de réponse sont mis en cache. Cela prend effet lorsque l'en-tête de la réponse est trop grand, auquel cas nous recevons un message disant upstream sent too big header while reading response header from upstream, ce qui est totalement différent de connection reset by peer.

Étant donné que ce type d'erreur est un déclencheur aléatoire, je vous suggère de vérifier si nginx utilise keepalive lors de la conversation en amont. Si tel était le cas, la connexion pourrait être réinitialisée par le serveur en amont à l'expiration du délai d'inactivité, alors que nginx ne savait pas que la connexion avait été interrompue, d'où le transfert de la demande en utilisant la même connexion. 

Autant que je sache, il n'y a pas de solution élégante pour y remédier. Vous pouvez réessayer ou définir une valeur keepalive_timeout dans le pool de connexions en amont dans nginx pour éviter le problème.

référencement:

Erreur temporaire Apache HttpClient: NoHttpResponseException

http://tengine.taobao.org/document/http_upstream_keepalive_timeout.html

0
bjrara

--post-buffering 32768 a travaillé pour moi comme suggéré (et déconseillé) ici NGINX + uWSGI Connection Reset by Peer

Je n'ai pas le temps d'enquêter plus à ce sujet pour le moment (mode de prototypage rapide :), mais comme il m'a fallu beaucoup de temps pour trouver ce hack, il pourrait être intéressant de le publier ici.

0
Łukasz Kidziński