Articles

NGINX 502 Bad Gateway: PHP-FPM

Tipp / nginx /502 bad gateway /php

Anmerkung des Herausgebers: php-fpm verwendet den Begriff „Master“, um seinen primären Prozess zu beschreiben. Datadog verwendet diesen Begriff nicht. In diesem Blogbeitrag werden wir dies als „primär“ bezeichnen, außer aus Gründen der Klarheit in Fällen, in denen wir auf einen bestimmten Prozessnamen verweisen müssen.

Dieser Beitrag ist Teil einer Serie zur Fehlerbehebung bei NGINX 502 Bad Gateway-Fehlern. Wenn Sie PHP-FPM nicht verwenden, lesen Sie unseren anderen Artikel zur Fehlerbehebung bei NGINX 502 mit Gunicorn als Backend.

PHP-FastCGI Process Manager (PHP-FPM) ist ein Daemon für die Verarbeitung von Webserver-Anfragen für PHP-Anwendungen. In der Produktion wird PHP-FPM häufig hinter einem NGINX-Webserver bereitgestellt. NGINX Proxies Web-Anfragen und leitet sie an PHP-FPM Worker-Prozesse, die die PHP-Anwendung ausführen.

Ein Diagramm zeigt den Fluss der Anfragen vom Browser zu NGINX zu PHP-FPM und zurück.

NGINX gibt einen 502 Bad Gateway-Fehler zurück, wenn es eine Anfrage nicht erfolgreich an PHP-FPM weiterleiten kann oder wenn PHP-FPM nicht antwortet. In diesem Beitrag untersuchen wir einige häufige Ursachen für 502-Fehler im NGINX / PHP-FPM-Stack und geben Anleitungen, wo Sie Informationen finden, die Ihnen bei der Behebung dieser Fehler helfen können.

Untersuchen Sie die Metriken, Protokolle und Spuren hinter NGINX 502 Bad Gateway-Fehlern mithilfe von Datadog.

Einige mögliche Ursachen für 502s

In diesem Abschnitt beschreiben wir, wie die folgenden Bedingungen dazu führen können, dass NGINX einen 502-Fehler zurückgibt:

  • PHP-FPM läuft nicht
  • NGINX kann nicht mit PHP-FPM kommunizieren
  • PHP-FPM läuft ab
  • PHP-FPM Aus einem dieser Gründe wird es mit einem 502-Fehler antworten und dies in seinem Zugriffsprotokoll (/ var/log/ nginx/access.log), wie in diesem Beispiel gezeigt:

    Zugriff.log

    Kopieren
    127.0.0.1 - - "GET / HTTP/1.1" 502 182 "-" "curl/7.58.0"

    Das NGINX-Zugriffsprotokoll erklärt nicht die Ursache eines 502-Fehlers, aber Sie können das Fehlerprotokoll (/var/log/nginx/error.log), um mehr zu erfahren. Zum Beispiel ist hier ein entsprechender Eintrag im NGINX-Fehlerprotokoll, der zeigt, dass die Ursache des 502-Fehlers darin besteht, dass der Socket nicht existiert, möglicherweise weil PHP-FPM nicht ausgeführt wird. (Im nächsten Abschnitt erfahren Sie, wie Sie dieses Problem erkennen und beheben können.)

    Fehler.log

    Kopieren
    2020/01/31 18:30:55 13617#13617: *557 connect() to unix:/run/php/php7.2-fpm.sock failed (2: No such file or directory) while connecting to upstream, client: 127.0.0.1, server: localhost, request: "GET / HTTP/1.1", upstream: "fastcgi://unix:/run/php/php7.2-fpm.sock:", host: "localhost"

    PHP-FPM läuft nicht

    Hinweis: Dieser Abschnitt enthält einen Prozessnamen, der den Begriff „master“ verwendet.“ Außer in Bezug auf bestimmte Prozesse verwendet dieser Artikel stattdessen den Begriff „Primär“.

    Wenn PHP-FPM nicht ausgeführt wird, gibt NGINX einen 502-Fehler für jede Anforderung zurück, die die PHP-Anwendung erreichen soll. Wenn Sie 502s sehen, überprüfen Sie zuerst, ob PHP-FPM ausgeführt wird. Auf einem Linux-Host können Sie beispielsweise einen ps -Befehl wie diesen verwenden, um nach laufenden PHP-FPM-Prozessen zu suchen:

    Kopieren
    sudo ps aux | grep 'php'

    PHP-FPM organisiert seine Arbeitsprozesse in Gruppen, die als Pools bezeichnet werden. Die folgende Beispielausgabe zeigt, dass der primäre PHP-FPM-Prozess ausgeführt wird, ebenso wie zwei Arbeitsprozesse im Standardpool (mit dem Namen www):

    Kopieren
    root 29852 0.0 2.2 435484 22396 ? Ssl 16:27 0:00 php-fpm: master process (/etc/php/7.2/fpm/php-fpm.conf)www-data 29873 0.0 1.5 438112 15220 ? Sl 16:27 0:00 php-fpm: pool wwwwww-data 29874 0.0 1.6 438112 16976 ? Sl 16:27 0:00 php-fpm: pool www

    Wenn die Ausgabe des Befehls ps keine PHP-FPM-Primär- oder Poolprozesse anzeigt, müssen Sie PHP-FPM zum Laufen bringen, um die 502-Fehler zu beheben.

    In einer Produktionsumgebung sollten Sie systemd verwenden, um PHP-FPM als Dienst auszuführen. Dies kann Ihre PHP-Anwendung zuverlässiger und skalierbarer machen, da der PHP-FPM-Daemon Ihre PHP-App automatisch bereitstellt, wenn Ihr Server gestartet wird oder wenn eine neue Instanz gestartet wird. PHP-FPM ist im PHP-Quellcode enthalten, sodass Sie PHP-FPM als Systemd-Dienst hinzufügen können, wenn Sie PHP konfigurieren.

    Sobald Ihr PHP-FPM-Projekt als Dienst konfiguriert ist, können Sie mit dem folgenden Befehl sicherstellen, dass es beim Start Ihres Servers automatisch gestartet wird:

    Kopieren
    sudo systemctl enable php7.2-fpm.service

    Anschließend können Sie den Befehl list-unit-files verwenden, um Informationen zu ihr Service:

    Kopieren
    sudo systemctl list-unit-files | grep -E 'php*fpm'

    Auf einem PHP 7.2 server, auf dem PHP-FPM installiert ist (auch wenn es nicht ausgeführt wird), lautet die Ausgabe dieses Befehls:

    Copy
    php7.2-fpm.service enabled

    Verwenden Sie diesen Befehl, um Informationen zu Ihrem PHP-FPM-Dienst anzuzeigen:

    Copy
    sudo systemctl is-active php7.2-fpm.service

    Dieser Befehl sollte eine Ausgabe von active . Wenn dies nicht der Fall ist, können Sie den Dienst mit starten:

    Kopieren
    sudo service php7.2-fpm start

    NGINX kann nicht auf den Socket zugreifen

    Wenn PHP-FPM startet, erstellt es einen oder mehrere TCP- oder Unix-Sockets, um mit dem NGINX-Webserver zu kommunizieren. Die Worker-Prozesse von PHP-FPM verwenden diese Sockets, um auf Anforderungen von NGINX zu warten.

    Um festzustellen, ob ein 502-Fehler durch eine Socket-Fehlkonfiguration verursacht wurde, bestätigen Sie, dass PHP-FPM und NGINX so konfiguriert sind, dass sie denselben Socket verwenden. PHP-FPM verwendet eine separate Konfigurationsdatei für jeden Worker-Prozesspool; Diese Dateien befinden sich unter /etc/php/7.2/fpm/pool.d/. Der Socket jedes Pools ist in einer listen Direktive in der Konfigurationsdatei des Pools definiert. Zum Beispiel konfiguriert die listen Direktive unten einen Pool mit dem Namen mypool, um einen Unix-Socket zu verwenden, der sich unter /run/php/mypool .socke:

    mypool.conf

    Copy
    listen = /run/php/mypool.sock

    Wenn NGINX nicht auf den Socket für einen bestimmten Pool zugreifen kann, können Sie feststellen, welcher Worker-Pool an dem Problem beteiligt ist, indem Sie überprüfen, welcher Socket im NGINX-Fehlerprotokolleintrag benannt ist. Wenn PHP-FPM beispielsweise den mypool Worker-Pool nicht gestartet hätte, würde NGINX eine 502 zurückgeben und sein Fehlerprotokolleintrag würde Folgendes enthalten:

    Fehler.log

    Kopieren
    connect() to unix:/run/php/mypool.sock failed (2: No such file or directory)

    Überprüfen Sie Ihren nginx.conf-Datei, um sicherzustellen, dass der relevante location -Block denselben Socket angibt. Das folgende Beispiel enthält eine include Direktive, die einige allgemeine Konfigurationsinformationen für PHP-FPM lädt, und eine fastcgi_pass Direktive, die denselben Unix-Socket angibt, der im mypool benannt ist.conf-Datei, oben.

    nginx.conf

    Kopieren
    location / { include snippets/fastcgi-php.conf; fastcgi_pass unix:/run/php/mypool.sock;}

    Unix-Sockets unterliegen Unix-Dateisystemberechtigungen. Die Konfigurationsdatei des PHP-FPM-Pools gibt den Modus und den Besitz des Sockets an, wie hier gezeigt:

    www.conf

    Copy
    listen.owner = www-datalisten.group = www-datalisten.mode = 0660

    Stellen Sie sicher, dass diese Berechtigungen dem Benutzer und der Gruppe, die NGINX ausführen, den Zugriff auf den Socket ermöglichen. Wenn die Berechtigungen für den Socket falsch sind, protokolliert NGINX einen 502-Fehler in seinem Zugriffsprotokoll und eine Meldung wie die unten gezeigte in seinem Fehlerprotokoll:

    error .log

    Kopieren
    2020/02/20 17:12:03 3059#3059: *4 connect() to unix:/run/php/mypool.sock failed (13: Permission denied) while connecting to upstream, client: 127.0.0.1, server: localhost, request: "GET / HTTP/1.1", upstream: "fastcgi://unix:/run/php/mypool.sock:", host: "localhost"

    Beachten Sie, dass die Standardwerte von listen.owner und listen.group mit dem Standardbesitzer und der Gruppe übereinstimmen, die NGINX ausführen, und listen.mode standardmäßig 0660. Mit diesen Standardeinstellungen sollte NGINX auf den Socket zugreifen können.

    Wenn PHP-FPM einen TCP-Socket überwacht, hat die listen Direktive der Poolkonfiguration einen Wert in der Form address:port, wie unten gezeigt:

    www.conf

    Copy
    listen = 127.0.0.1:9000

    Genau wie bei einem Unix-Socket können Sie 502-Fehler verhindern, indem Sie bestätigen, dass die Position dieses Sockets mit der in der NGINX-Konfiguration angegebenen übereinstimmt.

    PHP-FPM läuft ab

    Wenn die Antwort Ihrer Anwendung zu lange dauert, tritt bei Ihren Benutzern ein Timeout-Fehler auf. Wenn das Timeout von PHP-FPM — das in der Direktive request_terminate_timeout der Poolkonfiguration festgelegt ist (und standardmäßig 20 Sekunden beträgt) – kleiner ist als das Timeout von NGINX (standardmäßig 60 Sekunden), antwortet NGINX mit einem 502-Fehler. Das unten gezeigte NGINX-Fehlerprotokoll zeigt an, dass der vorgelagerte Prozess — PHP-FPM — die Verbindung geschlossen hat, bevor eine gültige Antwort gesendet wurde. Mit anderen Worten, dies ist das Fehlerprotokoll, das wir sehen, wenn PHP-FPM eine Zeitüberschreitung aufweist:

    error .log

    Kopieren
    2020/02/20 17:17:12 3059#3059: *29 recv() failed (104: Connection reset by peer) while reading response header from upstream, client: 127.0.0.1, server: localhost, request: "GET / HTTP/1.1", upstream: "fastcgi://unix:/run/php/mypool.sock:", host: "localhost"

    In diesem Fall das PHP-FPM-Protokoll (das sich standardmäßig unter /var/log/php7.2-fpm befindet.log) zeigt eine korrelierte Nachricht, die weitere Informationen liefert:

    php7.2-fpm.log

    Copy
     WARNING: child 2120, script '/var/www/html/index.php' (request: "GET /index.php") execution timed out (25.755070 sec), terminating

    Sie können die Timeout-Einstellung von PHP-FPM erhöhen, indem Sie die Konfigurationsdatei des Pools bearbeiten. Das Standard-NGINX-Timeout beträgt 60 Sekunden; wenn Sie Ihr PHP-FPM-Timeout über 60 Sekunden erhöht haben, gibt NGINX einen 504 Gateway-Timeout-Fehler zurück, wenn Ihre PHP-Anwendung nicht rechtzeitig geantwortet hat. Sie können dies verhindern, indem Sie auch Ihr NGINX-Timeout erhöhen. Im folgenden Beispiel haben wir den Timeout-Wert auf 90 Sekunden erhöht, indem wir den fastcgi_read_timeout -Eintrag zum http -Block von /etc/nginx/nginx hinzugefügt haben.conf:

    nginx.conf

    Kopieren
    http { ... fastcgi_buffers 8 16k; fastcgi_buffer_size 32k; fastcgi_connect_timeout 90; fastcgi_send_timeout 90; fastcgi_read_timeout 90;}

    Laden Sie Ihre NGINX-Konfiguration neu, um diese Änderung zu übernehmen:

    Kopieren
    nginx -s reload

    Um festzustellen, warum PHP-FPM abgelaufen ist, können Sie als nächstes Protokolle und APM-Daten (Application Performance Monitoring) sammeln, die Ursachen für die Latenz innerhalb und außerhalb Ihrer Anwendung aufdecken können.

    Sammeln und Analysieren Sie Ihre Protokolle

    Um Anwendungsfehler zu beheben, können Sie Ihre Protokolle sammeln und an einen Protokollverwaltungsdienst senden. Zusätzlich zu den oben untersuchten NGINX-Protokollen kann PHP Fehler und andere Ereignisse protokollieren, die für Sie wertvoll sein könnten. Weitere Informationen finden Sie in unserem PHP Logging Guide.

    Wenn Sie Ihre PHP- und NGINX-Protokolle in einen Protokollverwaltungsdienst einbinden, kombiniert mit Protokollen von relevanten Technologien wie Caching-Servern und Datenbanken, können Sie Protokolle aus Ihrem gesamten Web-Stack auf einer einzigen Plattform analysieren.

    Ein Balkendiagramm in Datadog Log Analytics visualisiert PHP- und NGINX-Protokolle mit unterschiedlichen Status wie Fehler, Warnung und Informationen.
    Die Protokollanalyse von Datadog zeigt Protokolle mehrerer Dienste nach Status gruppiert an.

    Sammeln Sie APM-Daten von Ihrem Webstack

    APM kann Ihnen helfen, Engpässe zu identifizieren und Probleme wie 502-Fehler zu beheben, die sich auf die Leistung Ihrer App auswirken. Der folgende Screenshot zeigt die in Datadog visualisierten APM-Daten von NGINX. Diese Ansicht fasst das Anforderungsvolumen, die Fehlerraten und die Latenz für einen NGINX-basierten Dienst zusammen und hilft Ihnen bei der Untersuchung von Leistungsproblemen wie 502-Fehlern.

    Eine Ansicht eines NGINX-Dienstes in Datadog APM enthält Balkendiagramme, die das Volumen der Anforderungen und Fehler anzeigen, ein Histogramm mit Latenzverteilung und ein Liniendiagramm mit Latenzwerten über die Zeit.

    200 OK

    Je schneller Sie die 502-Fehler Ihrer Anwendung diagnostizieren und beheben können, desto besser. Mit Datadog können Sie Metriken, Traces, Protokolle und Netzwerkleistungsdaten aus Ihrer gesamten Infrastruktur analysieren. Wenn Sie bereits Datadog-Kunde sind, können Sie mit der Überwachung von NGINX, PHP-FPM und mehr als 400 anderen Technologien beginnen. Wenn Sie noch kein Datadog-Konto haben, melden Sie sich für eine 14-tägige kostenlose Testversion an und legen Sie in wenigen Minuten los.