NGINX: Zeitüberschreitung beim Upstream (110: Zeitüberschreitung bei Verbindung) beim Lesen des Antwortheaders vom Upstream

130

Ich habe Puma als Upstream-App-Server und Riak als Hintergrund-DB-Cluster. Wenn ich eine Anfrage sende, die einen Datenblock für etwa 25.000 Benutzer auf der Karte reduziert und von Riak an die App zurückgibt, wird im Nginx-Protokoll eine Fehlermeldung angezeigt:

Zeitüberschreitung beim Upstream (110: Zeitüberschreitung der Verbindung) beim Lesen des Antwortheaders vom Upstream

Wenn ich meinen Upstream direkt ohne Nginx-Proxy mit derselben Anfrage abfrage, erhalte ich die erforderlichen Daten.

Das Nginx-Timeout tritt auf, sobald der Proxy eingegeben wurde.

**nginx.conf**

http {
    keepalive_timeout 10m;
    proxy_connect_timeout  600s;
    proxy_send_timeout  600s;
    proxy_read_timeout  600s;
    fastcgi_send_timeout 600s;
    fastcgi_read_timeout 600s;
    include /etc/nginx/sites-enabled/*.conf;
}

**virtual host conf**

upstream ss_api {
  server 127.0.0.1:3000 max_fails=0  fail_timeout=600;
}

server {
  listen 81;
  server_name xxxxx.com; # change to match your URL

  location / {
    # match the name of upstream directive which is defined above
    proxy_pass http://ss_api; 
    proxy_set_header  Host $http_host;
    proxy_set_header  X-Real-IP  $remote_addr;
    proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_cache cloud;
    proxy_cache_valid  200 302  60m;
    proxy_cache_valid  404      1m;
    proxy_cache_bypass $http_authorization;
    proxy_cache_bypass http://ss_api/account/;
    add_header X-Cache-Status $upstream_cache_status;
  }
}

Nginx hat eine Reihe von Timeout-Anweisungen. Ich weiß nicht, ob mir etwas Wichtiges fehlt. Jede Hilfe wäre sehr dankbar ....

user2768537
quelle
Es sollte erst nach 600s eine Zeitüberschreitung sein, oder? Sie können es fälschen, um die Zeit zu bestimmen, indem Sie auf 127.0.0.1:3000 einen TCP-Server einrichten, der nur Verbindungen akzeptiert und nichts damit macht, um zu sehen, wie lange es dauert. Es sollte 600s sein ...
Rogerdpack

Antworten:

46

Dies liegt daran, dass Ihr Upstream zu viel Zeit benötigt, um die Anfrage zu beantworten, und NGINX glaubt, dass der Upstream die Anfrage bereits nicht verarbeitet hat, und antwortet daher mit einem Fehler. Fügen Sie einfach proxy_read_timeout in den locationKonfigurationsblock ein und erhöhen Sie ihn . Das Gleiche ist mir passiert und ich habe 1 Stunde Timeout für eine interne App bei der Arbeit verwendet:

proxy_read_timeout 3600;

Damit wartet NGINX eine Stunde (3600s), bis sein Upstream etwas zurückgibt.

Sergio Gonzalez
quelle
6
Beachten Sie, dass es proxy_read_timeoutim Abschnitt http möglicherweise nicht hilfreich ist. Ich habe die proxy_passDirektive im Standortbereich und nur dort hat die proxy_read_timeoutEinstellung einen Unterschied gemacht. (Nginx 1.16.0)
JonnyJD
Scheint für mich in http / server / location zu funktionieren ... vielleicht haben sich die Dinge geändert :)
Rogerdpack
38

Sie sollten es immer unterlassen, die Zeitüberschreitungen zu erhöhen. Ich bezweifle, dass Ihre Backend-Server-Antwortzeit hier auf jeden Fall das Problem ist.

Ich habe dieses Problem umgangen, indem ich das Verbindungs-Keep-Alive-Flag gelöscht und die http-Version gemäß der Antwort hier angegeben habe: https://stackoverflow.com/a/36589120/479632

server {
    location / {
        proxy_set_header   X-Real-IP $remote_addr;
        proxy_set_header   Host      $http_host;

        # these two lines here
        proxy_http_version 1.1;
        proxy_set_header Connection "";

        proxy_pass http://localhost:5000;
    }
}

Leider kann ich nicht erklären, warum dies funktioniert, und habe es auch nicht geschafft, es aus den in der Antwort verlinkten Dokumenten zu entschlüsseln. Wenn also jemand eine Erklärung hat, wäre ich sehr interessiert, sie zu hören.

Almund
quelle
1
Warum sollten Sie das nicht anpassen, proxy_read_timeoutwenn Sie wissen, dass der Proxy (wenn auch nur für eine bestimmte URL) mehr Verarbeitungszeit benötigt?
Josh M.
Hallo! Ich erinnere mich nicht mehr an das genaue Problem, aber ich denke, es hing nicht mit der tatsächlichen Zeit für die URL zusammen, sondern damit, dass das Zeitlimit ohne diese Einstellungen nicht korrekt verarbeitet wurde.
Almund
@magicbacon das war vor Jahren, also erinnere ich mich kaum noch an den Fall, aber du hast das $http_hostRecht geändert ? Ich vermute, das würde nicht für https fliegen. Möglicherweise sind auch zusätzliche Einstellungen für die Weitergabe von https-Anforderungen erforderlich.
Almund
+1 ... das sieht nach einem umständlichen Hack aus, aber eigentlich ist dies aus den offiziellen Dokumenten :) nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive Ich habe ein etwas anderes Problem "Upstream vorzeitig geschlossene Verbindung beim Lesen der Antwort Header von Upstream "Wenn ich die Upstream-Direktive mit Keepalive verwende und diese beiden Zeilen verwende, scheint dies zu beheben.
Karussell
1
@ TimDavis Ich verstehe, vielleicht ist das besser. Ich denke, es könnte vom Datenverkehr abhängen, wie in diesem Beitrag angegeben, der für WebSockets erforderlich ist: serverlab.ca/tutorials/linux/web-servers-linux/…
Almund
26

Stellen Sie zunächst anhand der Nginx-Fehlerprotokolldatei fest, welcher Upstream langsamer wird, und passen Sie die Lesezeit entsprechend an, in meinem Fall war es fastCGI

2017/09/27 13:34:03 [error] 16559#16559: *14381 upstream timed out (110: Connection timed out) while reading response header from upstream, client:xxxxxxxxxxxxxxxxxxxxxxxxx", upstream: "fastcgi://unix:/var/run/php/php5.6-fpm.sock", host: "xxxxxxxxxxxxxxx", referrer: "xxxxxxxxxxxxxxxxxxxx"

Also muss ich das fastcgi_read_timeout in meiner Serverkonfiguration anpassen

 location ~ \.php$ {
     fastcgi_read_timeout 240;
     ...
 }

Siehe: Originalbeitrag

Ruberandinda Geduld
quelle
Hier ist eine Möglichkeit, Timing-Informationen hinzuzufügen, wenn nicht angezeigt wird, wie viel Sie "benötigen", um sie zu erhöhen: stackoverflow.com/questions/18627469/… FWIW
rogerdpack
10

In Ihrem Fall hilft es eine kleine Optimierung im Proxy, oder Sie können "# Timeout-Einstellungen" verwenden.

location / 
{        

  # time out settings
  proxy_connect_timeout 159s;
  proxy_send_timeout   600;
  proxy_read_timeout   600;
  proxy_buffer_size    64k;
  proxy_buffers     16 32k;
  proxy_busy_buffers_size 64k;
  proxy_temp_file_write_size 64k;
  proxy_pass_header Set-Cookie;
  proxy_redirect     off;
  proxy_hide_header  Vary;
  proxy_set_header   Accept-Encoding '';
  proxy_ignore_headers Cache-Control Expires;
  proxy_set_header   Referer $http_referer;
  proxy_set_header   Host   $host;
  proxy_set_header   Cookie $http_cookie;
  proxy_set_header   X-Real-IP  $remote_addr;
  proxy_set_header X-Forwarded-Host $host;
  proxy_set_header X-Forwarded-Server $host;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
Dimitrios
quelle
Für mich macht es einen Unterschied, diese Einstellungen im Standortbereich zu haben . Es hat nicht geholfen, sie im http- Bereich zu haben (möglicherweise, weil ich sie auch proxy_passim Standortbereich hatte .
JonnyJD
Was genau optimieren Sie mit diesen Deklarationen?
Vlad
9

Ich denke, dieser Fehler kann aus verschiedenen Gründen auftreten, aber er kann spezifisch für das von Ihnen verwendete Modul sein. Zum Beispiel habe ich dies mit dem uwsgi-Modul gesehen, musste also "uwsgi_read_timeout" setzen.

Richard
quelle
2
Ich denke uwsgi_read_timeout 3600; proxy_send_timeout 3600; proxy_read_timeout 3600; funktioniert bei mir.
Tyan
8

Ich würde empfehlen, sich den error_logs, insbesondere den Upstream- Teil anzusehen, in dem ein spezifischer Upstream angezeigt wird, bei dem eine Zeitüberschreitung auftritt.

Darauf basierend können Sie dann einstellen proxy_read_timeout, fastcgi_read_timeoutoder uwsgi_read_timeout.

Stellen Sie außerdem sicher, dass Ihre Konfiguration geladen ist.

Weitere Details hier Nginx Upstream Timeout (warum und wie zu beheben)

Gansbrest
quelle
4

Wie viele andere hier bereits betont haben, kann das Erhöhen der Timeout-Einstellungen für NGINX Ihr Problem lösen.

Das Erhöhen Ihrer Timeout-Einstellungen ist jedoch möglicherweise nicht so einfach, wie viele dieser Antworten vermuten lassen. Ich selbst war mit diesem Problem konfrontiert und habe versucht, meine Timeout-Einstellungen in der Datei /etc/nginx/nginx.conf zu ändern , wie fast jeder in diesen Threads vorschlägt. Das hat mir kein bisschen geholfen; Es gab keine offensichtliche Änderung der Timeout-Einstellungen von NGINX. Jetzt, viele Stunden später, konnte ich dieses Problem endlich beheben.

Die Lösung liegt in diesem Forenthread und es heißt, dass Sie Ihre Timeout-Einstellungen in /etc/nginx/conf.d/timeout.conf ablegen sollten (und wenn diese Datei nicht vorhanden ist, sollten Sie sie erstellen). Ich habe die gleichen Einstellungen verwendet, wie im Thread vorgeschlagen:

proxy_connect_timeout 600;
proxy_send_timeout 600;
proxy_read_timeout 600;
send_timeout 600;
Andreas Forslöw
quelle
1

Ich hatte das gleiche Problem und stellte fest, dass dies ein "täglicher" Fehler in der Schienensteuerung war. Ich weiß nicht warum, aber in der Produktion führt puma den Fehler immer wieder aus und verursacht die folgende Meldung:

Zeitlimit für Upstream (110: Zeitlimit für Verbindung) beim Lesen des Antwortheaders vom Upstream

Wahrscheinlich, weil Nginx immer wieder versucht, die Daten von Puma abzurufen. Das Lustige ist, dass der Fehler die Timeout-Meldung verursacht hat, selbst wenn ich eine andere Aktion im Controller aufrufe. Daher blockiert ein einziger Tippfehler die gesamte App.

Überprüfen Sie in Ihrer Datei log / puma.stderr.log, ob dies der Fall ist.

aarkerio
quelle
0

Von unserer Seite wurde spdy mit Proxy-Cache verwendet. Wenn der Cache abläuft, wird dieser Fehler angezeigt, bis der Cache aktualisiert wurde.

Timhaak
quelle
0

Hoffentlich hilft es jemandem: Ich bin auf diesen Fehler gestoßen und die Ursache war eine falsche Berechtigung für den Protokollordner für phpfpm. Nachdem ich ihn geändert hatte, damit phpfpm darauf schreiben konnte, war alles in Ordnung.

Maurício Otta
quelle
0

Für eine proxy_upstreamZeitüberschreitung habe ich die obige Einstellung ausprobiert, aber diese hat nicht funktioniert.

Die Einstellung resolver_timeoutfunktionierte für mich, da ich wusste, dass es 30 Sekunden dauerte, bis die Upstream-Timeout-Nachricht erstellt wurde. ZB me.atwibble.com nicht aufgelöst werden konnte (110: Operation timed out) .

http://nginx.org/en/docs/http/ngx_http_core_module.html#resolver_timeout

David Mercer
quelle