So diagnostizieren und beheben Sie Nginx 502 Bad Gateway-Fehler
Beheben Sie Nginx 502-Fehler durch Überprüfung der Fehlerprotokolle, Upstream-Integrität, Socket-Berechtigungen, Proxy-Einstellungen, Timeouts und Firewalls.
So diagnostizieren und beheben Sie Nginx 502 Bad Gateway-Fehler
Nginx ist ein leistungsstarker und beliebter Webserver und Reverse-Proxy, der häufig verwendet wird, um statische Inhalte bereitzustellen, den Datenverkehr zu verteilen und Anfragen an verschiedene vorgelagerte Anwendungsserver wie PHP-FPM, Node.js, Python Gunicorn oder Apache Tomcat weiterzuleiten. Wenn Nginx auf ein Problem bei der Kommunikation mit einem dieser vorgelagerten Server stößt, antwortet es in der Regel mit einem „502 Bad Gateway“-Fehler.
Beginnen Sie mit dem Nginx-Fehlerprotokoll und überprüfen Sie dann, ob der vorgelagerte Prozess läuft, erreichbar ist und antworten darf.
Den Nginx 502 Bad Gateway-Fehler verstehen
Ein 502 Bad Gateway-Fehler zeigt an, dass Nginx, das als Reverse-Proxy fungiert, eine ungültige Antwort von einem vorgelagerten Server erhalten hat. Das bedeutet, dass Nginx erfolgreich eine Verbindung zu einem vorgelagerten Server hergestellt hat, aber entweder keine Antwort, eine unvollständige Antwort oder eine Antwort erhalten hat, die es nicht verstehen konnte. Entscheidend ist, dass das Problem nicht bei Nginx selbst liegt, sondern bei dem Dienst, mit dem Nginx kommunizieren möchte.
Häufige vorgelagerte Server sind:
- PHP-FPM: Für PHP-Anwendungen (z. B. WordPress, Laravel).
- Gunicorn/uWSGI: Für Python-Anwendungen (z. B. Django, Flask).
- Node.js: Für JavaScript-Anwendungen.
- Apache Tomcat: Für Java-Anwendungen.
- Andere Webserver: Wie der Apache HTTP-Server, der bestimmte Inhalte bereitstellt.
Der 502-Fehler ist ein entscheidender Hinweis darauf, dass das Backend Ihrer Anwendung nicht richtig funktioniert oder für Nginx nicht erreichbar ist.
Schritt-für-Schritt-Diagnose
Der Schlüssel zur Behebung eines 502-Fehlers ist eine systematische Diagnose. Beginnen Sie mit den wahrscheinlichsten Ursachen und untersuchen Sie dann schrittweise weiter.
1. Überprüfen Sie zuerst die Nginx-Fehlerprotokolle
Ihre Nginx-Fehlerprotokolle sind die primäre Informationsquelle. Sie enthalten oft spezifische Details darüber, warum Nginx nicht mit dem vorgelagerten Server kommunizieren konnte.
- Speicherort: Normalerweise unter
/var/log/nginx/error.log. - Befehl: Verwenden Sie
tail -f, um die Protokolle in Echtzeit zu überwachen, während Sie versuchen, den Fehler zu reproduzieren.
tail -f /var/log/nginx/error.log
Worauf Sie achten sollten:
connect() failed (111: Connection refused): Zeigt an, dass der vorgelagerte Server nicht auf der angegebenen Adresse/dem angegebenen Port lauscht oder eine Firewall die Verbindung blockiert.upstream timed out: Der vorgelagerte Server hat zu lange gebraucht, um zu antworten.upstream prematurely closed connection: Der vorgelagerte Server hat die Verbindung geschlossen, bevor er eine vollständige Antwort gesendet hat.no live upstreams while connecting to upstream: Nginx konnte keine verfügbaren vorgelagerten Server in der Konfiguration finden.
2. Überprüfen Sie den Status des vorgelagerten Servers
Sobald Sie Hinweise aus den Nginx-Fehlerprotokollen haben, überprüfen Sie den Status Ihres vorgelagerten Anwendungsservers.
Für PHP-FPM:
sudo systemctl status php8.2-fpmFür Node.js/Python/andere benutzerdefinierte Apps: Überprüfen Sie, ob der Prozess läuft.
ps aux | grep node ps aux | grep gunicornWenn Sie einen Prozessmanager wie PM2 (Node.js) oder Supervisor (allgemein) verwenden, überprüfen Sie dessen Status.
pm2 status sudo supervisorctl status
Wenn der Dienst nicht läuft, versuchen Sie, ihn zu starten, und überprüfen Sie seine eigenen Protokolle auf Fehler.
sudo systemctl start php8.2-fpm
3. Überprüfen Sie die Netzwerkkonnektivität zum vorgelagerten Server
Stellen Sie sicher, dass Nginx den vorgelagerten Server auf dem konfigurierten Port oder Socket-Pfad erreichen kann.
Für TCP/IP-Verbindungen (z. B.
127.0.0.1:8000): Verwenden Sietelnetodernc(netcat), um die Port-Konnektivität vom Nginx-Server aus zu testen.telnet 127.0.0.1 8000 nc -vz 127.0.0.1 8000Eine erfolgreiche Verbindung sollte
Connected to 127.0.0.1.odersucceeded!anzeigen. Wenn es hängt oderConnection refusedanzeigt, lauscht der vorgelagerte Dienst nicht oder eine Firewall blockiert ihn.Für Unix-Sockets (z. B.
unix:/run/php/phpX.X-fpm.sock): Überprüfen Sie, ob die Socket-Datei existiert und die richtigen Berechtigungen hat.ls -l /run/php/phpX.X-fpm.sockNginx sollte Lese-/Schreibberechtigungen für diese Socket-Datei haben. Der Nginx-Benutzer (z. B.
www-data) muss Teil der Gruppe sein, die den Socket besitzt (z. B.www-dataoderphp-fpm).
Häufige Ursachen und Lösungen
Basierend auf Ihren Diagnoseschritten sind hier die häufigsten Ursachen für 502-Fehler und wie Sie sie beheben können.
1. Vorgelagerter Server läuft nicht oder ist abgestürzt
Ursache: Die Anwendung, an die Nginx proxy weiterleiten soll (z. B. PHP-FPM, Gunicorn, Node.js-App), läuft nicht oder ist abgestürzt.
Lösung: Starten oder neu starten Sie den vorgelagerten Dienst.
# Beispiel für PHP-FPM
sudo systemctl start php8.2-fpm
# Wenn er bereits läuft und Sie einen Absturz vermuten, starten Sie ihn neu:
sudo systemctl restart php8.2-fpm
# Für benutzerdefinierte Anwendungen verwenden Sie deren spezifische Start-/Neustart-Befehle
Tipp: Stellen Sie sicher, dass Ihre vorgelagerten Dienste so konfiguriert sind, dass sie beim Systemstart automatisch starten. Für systemd-Dienste verwenden Sie systemctl enable phpX.X-fpm.
2. Überlastung des vorgelagerten Servers / Ressourcenerschöpfung
Ursache: Der vorgelagerte Server ist überlastet, ihm gehen Speicher, CPU oder Prozesslimits aus, sodass er nicht mehr antwortet oder neue Verbindungen ablehnt.
Symptome: Nginx-Fehlerprotokolle zeigen möglicherweise zeitweise connection refused oder upstream timed out, insbesondere unter Last. Systemüberwachungstools (top, htop, free -h) zeigen eine hohe Ressourcennutzung.
Lösungen:
Für PHP-FPM: Passen Sie die PHP-FPM-Pool-Einstellungen in der Konfigurationsdatei an (z. B.
/etc/php/X.X/fpm/pool.d/www.conf).pm.max_children: Die maximale Anzahl von Kindern, die gleichzeitig aktiv sein können.pm.start_servers: Die Anzahl der Kinder, die beim Start erstellt werden.pm.min_spare_servers,pm.max_spare_servers: Steuert, wie viele untätige Kinder vorgehalten werden.
; Beispiel für dynamische Prozessverwaltung pm = dynamic pm.max_children = 50 pm.start_servers = 10 pm.min_spare_servers = 5 pm.max_spare_servers = 20- Erhöhen Sie
memory_limitin derphp.ini, wenn Skripte den Speicher erschöpfen.
Für andere Anwendungen: Erhöhen Sie die Anzahl der Worker-Prozesse, Threads oder weisen Sie nach Möglichkeit mehr Speicher zu. Überwachen Sie die spezifischen Metriken Ihrer Anwendung.
Nginx-Timeouts: Erhöhen Sie die Nginx-Direktiven
proxy_connect_timeout,proxy_send_timeoutundproxy_read_timeoutin Ihrer Nginx-Konfiguration, aber verstehen Sie, dass dies den Fehler nur verzögert, wenn das Backend wirklich überlastet ist.http { ... proxy_connect_timeout 60s; proxy_send_timeout 60s; proxy_read_timeout 60s; ... }
3. Falsche vorgelagerte Konfiguration in Nginx
Ursache: Nginx ist so konfiguriert, dass es eine Verbindung zur falschen IP-Adresse, zum falschen Port oder Unix-Socket-Pfad für den vorgelagerten Server herstellt.
Symptome: Nginx-Fehlerprotokolle zeigen sofort nach einer Anfrage connect() failed (111: Connection refused).
Lösung: Überprüfen Sie sorgfältig Ihre Nginx-Serverblock-Konfiguration (/etc/nginx/sites-available/your_site.conf).
Für HTTP/HTTPS-Upstreams:
location /app { proxy_pass http://127.0.0.1:8000; # Stellen Sie sicher, dass IP und Port korrekt sind proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; }Für PHP-FPM über Unix-Socket:
location ~ \.php$ { fastcgi_pass unix:/run/php/phpX.X-fpm.sock; # Überprüfen Sie, ob dieser Pfad genau mit der PHP-FPM-Konfiguration übereinstimmt fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; }Für PHP-FPM über TCP/IP:
location ~ \.php$ { fastcgi_pass 127.0.0.1:9000; # Überprüfen Sie IP und Port fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; }
Testen Sie nach Änderungen immer Ihre Nginx-Konfiguration und laden Sie Nginx neu/starten Sie es neu:
nginx -t
systemctl reload nginx # Oder restart, wenn -t darauf hinweist
4. PHP-FPM request_terminate_timeout überschritten
Ursache: Ein PHP-Skript benötigt länger für die Ausführung als die Einstellung request_terminate_timeout in PHP-FPM. Nginx wartet auf die Antwort, aber PHP-FPM beendet das Skript, sodass Nginx eine unvollständige Antwort erhält.
Symptome: Nginx-Fehlerprotokolle zeigen möglicherweise upstream timed out oder script timed out. PHP-FPM-Protokolle zeigen möglicherweise child XX exited on signal 9 (SIGKILL).
Lösung:
Erhöhen Sie
request_terminate_timeout: Finden und passen Sie diese Direktive in Ihrer PHP-FPM-Pool-Konfiguration (www.conf) an. Wenn Sie sie auf0setzen, wird das Timeout deaktiviert, was jedoch im Allgemeinen nicht empfohlen wird, da lang laufende Skripte Ressourcen blockieren können.request_terminate_timeout = 300 # Erhöhen auf 5 Minuten (300 Sekunden)Erhöhen Sie
fastcgi_read_timeoutin Nginx: Dieses Nginx-Timeout sollte gleich oder größer alsrequest_terminate_timeoutsein.location ~ \.php$ { ... fastcgi_read_timeout 300s; # Muss >= PHP-FPM's request_terminate_timeout sein ... }
Warnung: Das Erhöhen von Timeouts kann den 502-Fehler beheben, aber es kann zugrunde liegende Leistungsprobleme überdecken. Die beste langfristige Lösung ist die Optimierung des langsamen PHP-Skripts.
5. Firewall-Probleme
Ursache: Eine Firewall (entweder auf dem Nginx-Server oder auf dem vorgelagerten Server, wenn sie getrennt sind) blockiert Verbindungen zum vorgelagerten Port oder Socket.
Lösung:
Firewall-Status überprüfen:
sudo ufw status # Für UFW (Ubuntu/Debian) sudo firewall-cmd --list-all # Für firewalld (CentOS/RHEL) sudo iptables -L # Für iptablesNotwendige Ports öffnen: Stellen Sie sicher, dass der Port, den Nginx für die Verbindung zum vorgelagerten Server verwendet (z. B. 9000 für PHP-FPM über TCP/IP), geöffnet ist.
sudo ufw allow from 127.0.0.1 to any port 9000 # Erlaube localhost, sich mit 9000 zu verbinden sudo firewall-cmd --permanent --add-port=9000/tcp # Für firewalld sudo firewall-cmd --reloadDeaktivieren Sie die Firewall vorübergehend zu Testzwecken nur in einer kontrollierten Umgebung und aktivieren und konfigurieren Sie sie dann ordnungsgemäß wieder.
6. SELinux- oder AppArmor-Interferenz
Ursache: Sicherheitserweiterungen wie SELinux (auf RHEL/CentOS) oder AppArmor (auf Ubuntu/Debian) könnten Nginx daran hindern, auf den vorgelagerten Socket zuzugreifen oder Netzwerkverbindungen herzustellen, selbst wenn Dateiberechtigungen und Firewalls korrekt konfiguriert sind.
Symptome: Protokolle zeigen möglicherweise permission denied oder ähnliche Meldungen, insbesondere in /var/log/audit/audit.log (für SELinux).
Lösung:
Überprüfen Sie
audit.log:sudo grep nginx /var/log/audit/audit.logSetzen Sie SELinux vorübergehend in den permissiven Modus:
sudo setenforce 0. Wenn der Fehler behoben ist, ist SELinux die Ursache. Sie müssen dann geeignete SELinux-Richtlinien generieren und anwenden (z. B.audit2allow). Denken Sie daran, es wieder in den enforcing-Modus zu setzen (sudo setenforce 1).Überprüfen Sie den AppArmor-Status:
sudo aa-status. Wenn AppArmor aktiv ist, müssen Sie möglicherweise das Nginx-Profil anpassen.
7. Große Anfrage-/Antwortkörper (Proxy-Pufferung)
Ursache: Die standardmäßigen Proxy-Puffereinstellungen von Nginx könnten für sehr große Anfrage- oder Antwortkörper zu klein sein, was zu einem vorzeitigen Verbindungsabbruch führt.
Symptome: Nginx-Fehlerprotokolle zeigen möglicherweise upstream prematurely closed connection while reading response header from upstream oder upstream prematurely closed connection while reading response body from upstream.
Lösung: Passen Sie die Nginx-Proxy-Puffer-Direktiven in Ihrem http-, server- oder location-Block an.
http {
...
proxy_buffer_size 128k; # Größe des Puffers für den ersten Teil der Antwort
proxy_buffers 4 256k; # Anzahl und Größe der Puffer für den Rest der Antwort
proxy_busy_buffers_size 256k; # Maximale Größe der belegten Puffer
proxy_temp_file_write_size 256k; # Größe für das Schreiben in temporäre Dateien, wenn die Pufferung überläuft
...
}
Hinweis: Diese Einstellungen verbrauchen mehr Speicher. Passen Sie sie vorsichtig an, basierend auf den Ressourcen Ihres Servers und der typischen Größe der Antworten Ihrer Anwendung.
Allgemeine Tipps zur Fehlerbehebung
- Überprüfen Sie alle relevanten Protokolle: Neben den Nginx-Fehlerprotokollen überprüfen Sie auch die Nginx-Zugriffsprotokolle, die Protokolle der vorgelagerten Anwendung (PHP-FPM, Gunicorn, Node.js-App-Protokolle) und Systemprotokolle (
/var/log/syslog,dmesg). - Nginx neu starten: Starten Sie Nginx nach Konfigurationsänderungen immer neu, um sicherzustellen, dass sie wirksam werden:
systemctl restart nginx. - Nginx-Konfiguration testen: Überprüfen Sie vor dem Neustart die Syntax Ihrer Nginx-Konfiguration:
nginx -t. - Problem isolieren: Versuchen Sie, Nginx zu umgehen und direkt auf die vorgelagerte Anwendung zuzugreifen. Wenn Ihre Node.js-App beispielsweise auf
localhost:3000läuft, verwenden Siecurl http://localhost:3000von der Befehlszeile des Servers aus. Wenn auch dies fehlschlägt, liegt das Problem definitiv bei Ihrer Anwendung, nicht bei Nginx. - Festplattenspeicher überprüfen: Eine volle Festplatte kann verhindern, dass Anwendungen temporäre Dateien oder Protokolle schreiben, was zu Abstürzen oder Fehlern führt. Verwenden Sie
df -h, um die Festplattennutzung zu überprüfen.
Fazit
Beginnen Sie mit /var/log/nginx/error.log und überprüfen Sie dann, ob der vorgelagerte Dienst läuft und vom Nginx-Host aus erreichbar ist. Sobald Sie wissen, ob der Fehler auf Verbindungsverweigerung, Timeout, Berechtigungsverweigerung oder vorzeitiges Schließen zurückzuführen ist, liegt die Behebung in der Regel beim vorgelagerten Dienst, den Socket-Berechtigungen, den Timeout-Einstellungen oder der Firewall-Regel.