Ich habe angefangen, Nginx als Reverse-Proxy für eine Reihe von Servern zu verwenden, die irgendeine Art von Dienst bereitstellen.
Der Dienst kann manchmal ziemlich langsam sein (er läuft auf Java und die JVM bleibt manchmal in der "vollständigen Garbage Collection" hängen, die mehrere Sekunden dauern kann), daher habe ich den proxy_connect_timeout
Wert auf 2 Sekunden gesetzt, damit Nginx genügend Zeit zum Ermitteln hat Stellen Sie sicher, dass der Dienst auf dem GC nicht mehr reagiert und die Anforderung nicht rechtzeitig an einen anderen Server weitergeleitet wird.
Ich habe auch festgelegt proxy_read_timeout
, dass der Reverse-Proxy nicht mehr reagiert, wenn der Dienst selbst zu viel Zeit für die Berechnung der Antwort benötigt. Auch hier sollte die Anforderung auf einen anderen Server verschoben werden, der frei genug sein sollte, um eine zeitnahe Antwort zurückzusenden.
Ich habe einige Benchmarks ausgeführt und kann deutlich sehen, dass das proxy_connect_timeout
ordnungsgemäß funktioniert, da einige Anforderungen genau zu der für das Verbindungszeitlimit angegebenen Zeit zurückkehren, da der Dienst feststeckt und eingehende Verbindungen nicht akzeptiert (der Dienst verwendet Jetty als eingebettetes Medium) Servlet-Container). Das proxy_read_timeout
funktioniert auch, da ich Anfragen sehen kann, die nach dem dort angegebenen Timeout zurückkehren.
Das Problem ist, dass ich erwartet hätte, dass einige Anfragen nach dieser Zeitüberschreitung proxy_read_timeout + proxy_connect_timeout
oder fast nach dieser Zeitspanne eingehen , wenn der Dienst nicht mehr funktioniert und keine Verbindungen akzeptiert, wenn Nginx versucht, darauf zuzugreifen, aber bevor Nginx eine Zeitüberschreitung ausführen kann - es wird freigegeben und startet die Verarbeitung, ist aber zu langsam und Nginx würde aufgrund des Zeitlimits für das Lesen abgebrochen. Ich glaube, dass der Service solche Fälle hat, aber nachdem ich mehrere Benchmarks mit insgesamt mehreren Millionen Anfragen ausgeführt habe, konnte ich keine einzige Anfrage sehen, die in irgendetwas weiter oben zurückkehrt proxy_read_timeout
(was das größere Timeout ist).
Ich würde mich über jeden Kommentar zu diesem Problem freuen, auch wenn ich denke, dass dies an einem Fehler in Nginx liegen könnte (ich muss mir den Code erst noch ansehen, dies ist nur eine Annahme), dass der Timeout-Zähler nach dem Herstellen der Verbindung nicht zurückgesetzt wird ist erfolgreich, wenn Nginx nichts vom Upstream-Server gelesen hat.
proxy_read_timeout
nicht das "globale Zeitlimit" angibt, sondern zwischen zwei Lesevorgängen.proxy_read_timeout + proxy_connect_timeout
.Antworten:
Ich konnte dies tatsächlich nicht reproduzieren auf:
Ich habe dies in meiner nginx.conf eingerichtet:
Ich habe dann zwei Testserver eingerichtet. Eine, die nur eine Zeitüberschreitung bei der SYN verursacht und eine, die Verbindungen akzeptiert, aber niemals antwortet:
Dann habe ich eine Testverbindung eingeschickt:
Dann schaute error_log, das dies zeigte:
dann:
Und dann das access.log mit dem erwarteten Timeout von 30s (10 + 20):
Hier ist das von mir verwendete Protokollformat, das die einzelnen Upstream-Timeouts enthält:
quelle
proxy_send_timeout
) zu schreiben, und da Sie sie höher als festgelegtproxy_connection_timeout
haben, kann dies tatsächlich eine Verzögerung über die 20 Sekunden erklärenproxy_read_timeout
. Wenn du sagst "spucke Linien wirklich langsam aus" - was meinst du damit?proxy_read_timeout
die Anforderung entweder vollständig fehlschlägt oder vollständig zugelassen wird. Dies erklärt auch den Unterschied zwischen dem Verhalten, das Sie sehen, und dem Verhalten, das ich sehe.Das Zeitlimit für die Verbindung bedeutet, dass TCP beim Handshake blockiert (z. B. gab es keine SYN_ACKs). TCP würde erneut versuchen, SYNs zu senden, aber Sie haben nur 2 Sekunden gegeben. Nginx zu gehen, einen anderen Server zu verwenden, so hat es einfach keine Zeit zum erneuten Senden von SYNs.
UPD. : Konnte nicht in Dokumenten gefunden werden, aber tcpdump zeigt, dass es 3 Sek. Gibt. Verzögerung zwischen dem ersten SYN-Sendeversuch und dem zweiten SYN-Sendeversuch.
quelle