Pufferanfragen für kurze Zeit an nginx, wenn das Backend nicht verfügbar ist

7

Ich habe eine NodeJS-App, die für immer hinter Nginx läuft. Wenn ich neuen Code bereitstelle, mache ich das nur, forever restartaber ich kann es mir nicht leisten, auch in dieser kurzen Zeit 502 zu bekommen.

Wie konfiguriere ich nginx so, dass es bei 502 weiterhin auf diesem Upstream-Server wiederholt wird? Ich habe versucht zu setzen proxy_connect_timeout, proxy_read_timeoutund proxy_send_timeoutzB 30saber ich bekomme sofort 502 egal was :(

Meine Website conf ist:

upstream my_server {
  server 127.0.0.1:3000 fail_timeout=0;
  keepalive 1024;
}

server {
 listen 3333;

server_name myservername.com;
access_log /var/log/nginx/my_server.log;

location / {
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header Host $http_host;
  proxy_set_header X-NginX-Proxy true;

  # retry upstream on 502 error
  proxy_connect_timeout      30s;
  proxy_send_timeout         30s;
  proxy_read_timeout         30s;

  proxy_pass http://my_server;
  proxy_http_version 1.1;
  proxy_set_header Connection "";
  proxy_redirect off;
 }
}

Ist es möglich, Anfragen für diese kurze Zeit zu puffern, wenn Upstream nicht verfügbar ist?

Marin
quelle

Antworten:

1

Dies klingt letztendlich nach einem Problem mit Ihrem Backend: nginx stellt eine Anfrage an Ihr Backend, die Verbindung wird sofort abgelehnt, sodass nginx keine andere Option hat, um einen Fehler stromabwärts an den Benutzer weiterzuleiten, da kein anderer Upstream angegeben ist. und die von timeoutIhnen angegebenen Werte haben hier keine Auswirkung, da nginx überhaupt nicht auf etwas warten muss.


Ich weiß jetzt nicht, was foreverist oder wie es funktioniert, aber es gibt ein paar mögliche Lösungen, die mir in den Sinn kommen.

Es gibt zwei Möglichkeiten, was auf der Upstream-Seite passiert:

  • "Forever" akzeptiert möglicherweise die Verbindung und gibt sofort einen Fehler zurück. In diesem Fall sollten Sie sich wirklich fragen, wie Sie die Verbindung nicht falsch handhaben können. Warten Sie jedoch, bis die Bereitstellung Ihrer App abgeschlossen ist, und verarbeiten Sie die Anforderung dann und dort. Die opengrokApp auf dem tomcatServer hat dieses Problem.

  • Niemand lauscht auf dem Port, an dem Ihre App ausgeführt werden soll. Daher löscht der Kernel das Paket sofort und gibt sofort ein TCP-RST-Paket zurück.

    • Wenn TCP RSTdie Ursache ist, können Sie es lösen , indem man foreverdie Abhörsocket halten, oder von der Kernel - Konfiguration eingehende Pakete für eine bestimmte Zeit in der Warteschlange, im Vorgriff auf jemandem , den sie bis später, so dass bei der Kommissionierung foreverstartet wieder nach oben, es‘ Ich habe eine ganze Warteschlange für die Wartung bereit.

    • Konfigurieren Sie den Kernel so, dass er keine TCP RSTProbleme verursacht, wenn niemand zuhört. Dann timeoutwirkt sich Ihr in nginx aus. Konfigurieren Sie anschließend nginxeine zweite Anforderung an einen anderen Upstream.

Wenn Sie einen der oben genannten Fälle ansprechen, sind Sie fertig.

Andernfalls müssen Sie versuchen, nginx zu konfigurieren, um das Problem zu beheben:

  • Sie könnten versuchen , proxy_cachemit proxy_cache_use_stale.

  • Sie könnten versuchen, den Fehlerbehandler zu verwenden: siehe proxy_intercept_errors(gilt wahrscheinlich nur, wenn der 503, den Sie erhalten, von Ihrem Backend übergeben wird) und error_page. Sie möchten Zeit im Fehlerbehandler verschwenden, bis Ihre App wieder hochgefahren ist, und dann eine Anfrage an Ihre App senden.

    • Sie könnten Zeit verschwenden, indem Sie eine zweite App ausführen, die einfach so sleep()lange dauert, bis Ihre App erneut bereitgestellt wird, und dann entweder eine HTTP-Umleitung bereitstellen oder ohne Antwort beenden. Zum Teufel, Sie könnten dies einfach implementieren, indem Sie versuchen, einen Proxy für einen TCP-Port zu erstellen, den Sie block dropin der Firewall haben, wodurch Ihre Zeitüberschreitungen in Nginx aktiviert werden. Konfigurieren Sie anschließend nginx für eine zweite Anforderung.

Wenn Sie einen der oben genannten Ansätze implementieren, der die timeoutAktivierung umfasst , muss anschließend eine zusätzliche Anforderung an das Backend gestellt werden. Sie können die upstreamDirektive dafür verwenden, wobei Sie entweder denselben Server mehrmals angeben oder, falls dies nicht akzeptiert wird, einen Port durch Ihre Firewall spiegeln können, oder, noch besser, Sie können tatsächlich mehrere unabhängige App-Server ausführen .

Das bringt uns zurück zu Ihrem App-Server: Wenn das Problem der sauberen erneuten Bereitstellung nicht gelöst werden kann, sollten Sie möglicherweise zwei solcher App-Server ausführen und nginx verwenden, um den Lastenausgleich zwischen ihnen durchzuführen. Oder stellen Sie sie erneut bereit und wechseln Sie dann zu Nginx auf die neue Kopie, sobald sie tatsächlich fertig ist. Wie können Sie sonst sicher sein, dass Ihre Kunden bereit sind, auch nur 30 Sekunden auf die Antwort Ihrer API zu warten?

cnst
quelle