J'ai commencé à utiliser Nginx comme proxy inverse pour un ensemble de serveurs qui fournissent une sorte de service.
Le service peut parfois être assez lent (son fonctionnement sur Java et la JVM est parfois coincé dans une "récupération de place complète" qui peut prendre plusieurs secondes), j'ai donc défini la valeur proxy_connect_timeout
à 2 secondes, ce qui donnera à Nginx suffisamment de temps pour comprendre que le service est bloqué sur GC et ne répondra pas à temps, et il doit transmettre la demande à un autre serveur.
J'ai également décidé proxy_read_timeout
d'empêcher le proxy inverse de se bloquer si le service lui-même prend trop de temps pour calculer la réponse - encore une fois, il devrait déplacer la demande vers un autre serveur qui devrait être suffisamment libre pour renvoyer une réponse en temps opportun.
J'ai exécuté des tests de performance et je peux voir clairement que cela proxy_connect_timeout
fonctionne correctement car certaines demandes retournent exactement à l'heure spécifiée pour le délai de connexion, car le service est bloqué et n'accepte pas les connexions entrantes (le service utilise Jetty comme un embarqué conteneur de servlet). Le proxy_read_timeout
fonctionne également, comme je peux voir que les demandes de retour après le délai spécifié il.
Le problème est que je m'attendais à voir certaines demandes qui expirent après proxy_read_timeout + proxy_connect_timeout
, ou presque cette durée, si le service est bloqué et n'accepte pas les connexions lorsque Nginx essaie d'y accéder, mais avant que Nginx ne puisse expirer - il est libéré et commence le traitement, mais est trop lent et Nginx serait abandonné en raison du délai de lecture. Je crois que le service a de tels cas, mais après avoir exécuté plusieurs tests de référence, totalisant plusieurs millions de demandes - je n'ai pas vu une seule demande qui retourne dans quoi que ce soit ci-dessus proxy_read_timeout
(qui est le plus grand délai d'attente).
J'apprécierais tout commentaire sur ce problème, bien que je pense que cela pourrait être dû à un bogue dans Nginx (je n'ai pas encore examiné le code, donc ce n'est qu'une hypothèse) que le compteur de délai d'attente n'est pas réinitialisé après la connexion est réussie, si Nginx n'a rien lu du serveur en amont.
proxy_read_timeout
n'est pas le «délai global», mais entre 2 opérations de lecture.proxy_read_timeout + proxy_connect_timeout
.Réponses:
Je n'ai en fait pas pu reproduire ceci sur:
J'ai mis cela en place dans mon nginx.conf:
J'ai ensuite installé deux serveurs de test. Un qui expirerait simplement sur le SYN et un qui accepterait les connexions mais ne répondrait jamais:
Ensuite, j'ai envoyé une connexion de test:
Puis regardé error_log qui a montré ceci:
ensuite:
Et puis le fichier access.log qui a le délai d'attente 30s prévu (10 + 20):
Voici le format de journal que j'utilise, qui inclut les délais d'attente individuels en amont:
la source
proxy_send_timeout
) et comme vous l'avez réglée à un niveau supérieurproxy_connection_timeout
, cela peut en fait expliquer tout retard au cours des 20 secondesproxy_read_timeout
. Lorsque vous dites "cracher des lignes très lentement" - que voulez-vous dire?proxy_read_timeout
que la demande échoue complètement ou l'autorise complètement. Cela explique également la différence entre le comportement que vous voyez et le comportement que je vois.Le délai d'expiration de la connexion signifie que TCP se bloque lors de l'établissement d'une liaison (par exemple, il n'y avait pas de SYN_ACK). TCP essaierait à nouveau d'envoyer des SYN, mais vous n'avez donné que 2 secondes. à Nginx pour utiliser un autre serveur, il n'a donc tout simplement pas le temps de renvoyer des SYN.
UPD. : Impossible de trouver dans les documents, mais tcpdump montre qu'il y a 3 secondes. délai entre le 1er SYN envoyé et la 2e tentative d'envoi du SYN.
la source