Articles

Nginx 502 Bad Gateway: PHP-FPM

tip / nginx /502 bad gateway /php

Uwaga wydawcy: php-FPM używa terminu „master” do opisania swojego podstawowego procesu. Datadog nie używa tego terminu. W tym poście na blogu będziemy określać to jako „podstawowe”, z wyjątkiem przypadków, w których musimy odwołać się do konkretnej nazwy procesu.

ten post jest częścią serii dotyczącej rozwiązywania problemów z błędnymi błędami bramki nginx 502. Jeśli nie używasz PHP-FPM, sprawdź nasz inny artykuł na temat rozwiązywania problemów z NGINX 502s z Gunicorn jako backendem.

PHP-FastCGI Process Manager (PHP-FPM) jest demonem do obsługi żądań serwera www dla aplikacji PHP. W produkcji PHP-FPM jest często wdrażany za serwerem internetowym NGINX. Proxy NGINX obsługują żądania sieciowe i przekazują je do procesów roboczych PHP-FPM, które wykonują aplikację PHP.

diagram pokazuje przepływ żądań z przeglądarki do nginx do PHP-FPM i z powrotem.

NGINX zwróci błąd 502 Bad Gateway, jeśli nie może pomyślnie przesłać żądania do PHP-FPM lub jeśli PHP-FPM nie odpowie. W tym poście przeanalizujemy niektóre typowe przyczyny błędów 502 w stosie Nginx / PHP-FPM i dostarczymy wskazówek, gdzie można znaleźć informacje, które mogą pomóc w rozwiązaniu tych błędów.

Przeglądaj metryki, dzienniki i ślady za błędnymi błędami bramki NGINX 502 za pomocą Datadog.

niektóre możliwe przyczyny 502s

w tej sekcji opiszemy, w jaki sposób następujące warunki mogą spowodować, że nginx zwróci błąd 502:

  • PHP-FPM nie działa
  • NGINX nie może komunikować się z PHP-FPM
  • PHP-FPM wyłącza czas

Jeśli nginx nie jest w stanie komunikować się z php-fpm z żadnego z tych powodów, odpowie z błędem 502, odnotowując to w swoim dzienniku dostępu (/var/log/nginx/access.log) jak pokazano w tym przykładzie:

access.log

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

dziennik dostępu NGINX nie wyjaśnia przyczyny błędu 502, ale możesz sprawdzić jego dziennik błędów (/var/log/nginx / error.log), aby dowiedzieć się więcej. Na przykład, tutaj jest odpowiedni wpis w dzienniku błędów NGINX, który pokazuje, że przyczyną błędu 502 jest to, że gniazdo nie istnieje, prawdopodobnie dlatego, że PHP-FPM nie jest uruchomione. (W następnej sekcji przyjrzymy się, jak wykryć i rozwiązać ten problem.)

błąd.log

Kopiuj
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 nie działa

Uwaga: Ta sekcja zawiera nazwę procesu, który używa terminu „master.”Z wyjątkiem przypadków, gdy odnosi się do konkretnych procesów, w tym artykule używa się zamiast tego terminu „pierwotny”.

Jeśli PHP-FPM nie jest uruchomiony, NGINX zwróci błąd 502 dla każdego żądania mającego dotrzeć do aplikacji PHP. Jeśli widzisz 502s, najpierw sprawdź, czy PHP-FPM jest uruchomione. Na przykład na hoście Linuksowym możesz użyć polecenia ps podobnego do tego, aby wyszukać uruchomione procesy PHP-FPM:

Kopiuj
sudo ps aux | grep 'php'

PHP-FPM organizuje swoje procesy robocze w grupach nazywa się baseny. Przykładowe wyjście poniżej pokazuje, że podstawowy proces PHP-FPM jest uruchomiony, podobnie jak dwa procesy robocze w domyślnej puli (o nazwie www):

Kopiuj
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

Jeśli wyjście polecenia ps nie pokazuje żadnych podstawowych lub puli procesów PHP-FPM, musisz uruchomić PHP-FPM, aby rozwiązać błędy 502.

w środowisku produkcyjnym powinieneś rozważyć użycie systemd do uruchomienia PHP-FPM jako usługi. Może to sprawić, że Twoja aplikacja PHP będzie bardziej niezawodna i skalowalna, ponieważ Demon PHP-FPM automatycznie zacznie obsługiwać Twoją aplikację PHP podczas uruchamiania serwera lub podczas uruchamiania nowej instancji. PHP-FPM jest zawarty w kodzie źródłowym PHP, więc możesz dodać PHP-FPM jako usługę systemd podczas konfigurowania PHP.

Po skonfigurowaniu projektu PHP-FPM jako usługi, możesz użyć następującego polecenia, aby upewnić się, że uruchamia się automatycznie podczas uruchamiania serwera:

Kopiuj
sudo systemctl enable php7.2-fpm.service

następnie możesz użyć list-unit-files polecenie, aby zobaczyć informacje o Twoim serwisie:

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

w PHP 7.2 serwer z zainstalowanym PHP-FPM (nawet jeśli nie jest uruchomiony), wyjście tego polecenia będzie następujące:

Kopiuj
php7.2-fpm.service enabled

aby zobaczyć informacje o usłudze PHP-FPM, użyj tego polecenia:

Kopiujolecenie to powinno zwracać dane wyjściowe o wartości

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

To polecenie powinno zwracać dane wyjściowe o wartości active. Jeśli nie, możesz uruchomić usługę z:

Kopiuj
sudo service php7.2-fpm start

NGINX nie może uzyskać dostępu do gniazda

podczas uruchamiania PHP-FPM tworzy jedno lub więcej gniazd TCP lub Unix, aby komunikować się z serwerem internetowym NGINX. Procesy robocze PHP-FPM używają tych gniazd do nasłuchiwania żądań od NGINX.

aby ustalić, czy błąd 502 był spowodowany błędną konfiguracją gniazda, upewnij się, że PHP-FPM i Nginx są skonfigurowane do używania tego samego gniazda. PHP-FPM używa oddzielnego pliku konfiguracyjnego dla każdej puli procesów roboczych; pliki te znajdują się w /etc/php/7.2/fpm/pool.d/. Gniazdo każdej puli jest zdefiniowane w dyrektywielisten w pliku konfiguracyjnym puli. Na przykład dyrektywa listen poniżej konfiguruje pulę o nazwie mypool, aby używać gniazda Unix znajdującego się w /run/php/mypool.

mypool.conf

Kopiuj
listen = /run/php/mypool.sock

Jeśli NGINX nie może uzyskać dostępu do gniazda dla określonej puli, możesz określić, która Pula robocza jest zaangażowana w problem, sprawdzając, które gniazdo jest nazwane we wpisie dziennika błędów NGINX. Na przykład, jeśli PHP-FPM nie uruchomił puli roboczejmypool, NGINX zwróci 502, a jego wpis w dzienniku błędów będzie zawierał:

błąd.Zaloguj

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

sprawdź swój nginx.plik conf, aby upewnić się, że odpowiedni blok location określa to samo gniazdo. Poniższy przykład zawiera dyrektywęinclude, która ładuje ogólne informacje konfiguracyjne dla PHP-FPM, oraz dyrektywęfastcgi_pass, która określa to samo gniazdo Unixowe nazwane w mypool.plik conf, powyżej.

nginx.conf

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

gniazda Unix podlegają uprawnieniom systemu plików Unix. Plik konfiguracyjny puli PHP-FPM określa tryb i własność gniazda, jak pokazano tutaj:

www.conf

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

upewnij się, że te uprawnienia pozwalają użytkownikowi i grupie uruchomionej NGINX uzyskać dostęp do gniazda. Jeśli uprawnienia do gniazda są nieprawidłowe, NGINX zarejestruje błąd 502 w swoim dzienniku dostępu i komunikat podobny do tego pokazanego poniżej w dzienniku błędów:

error.Zaloguj

Kopiuj
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"

zauważ, że domyślne wartościlisten.ownerIlisten.grouppasują do domyślnego właściciela i grupa działa nginx, alisten.mode domyślnie 0660. Korzystając z tych ustawień domyślnych, NGINX powinien mieć dostęp do gniazda.

Jeśli PHP-FPM nasłuchuje na gnieździe TCP, dyrektywalisten będzie miała wartość w postaciaddress:port, jak pokazano poniżej:

www.conf

Kopiuj
listen = 127.0.0.1:9000

podobnie jak w przypadku gniazda Unix, możesz zapobiec błędom 502, potwierdzając, że lokalizacja tego gniazda odpowiada lokalizacji podanej w konfiguracji NGINX.

PHP-FPM wyłącza czas

Jeśli Twoja aplikacja reaguje zbyt długo, Twoi użytkownicy będą mieli błąd limitu czasu. Jeśli timeout PHP-FPM-ustawiony w dyrektywie request_terminate_timeout konfiguracji puli (domyślnie 20 sekund) – jest mniejszy niż timeout NGINX (domyślnie 60 sekund), NGINX odpowie błędem 502. Dziennik błędów nginx pokazany poniżej wskazuje, że jego proces macierzysty—którym jest PHP-FPM—zamknął połączenie przed wysłaniem prawidłowej odpowiedzi. Innymi słowy, jest to dziennik błędów, który widzimy, gdy PHP-FPM kończy się:

błąd.log

Kopiuj
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"

w tym przypadku dziennik PHP-FPM (który domyślnie znajduje się w/var / log / php7.2-FPM.log) pokazuje skorelowany komunikat, który dostarcza dalszych informacji:

php7.2-fpm.log

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

możesz podnieść ustawienie limitu czasu PHP-FPM, edytując plik konfiguracyjny puli, ale może to spowodować inny problem: NGINX może wygasnąć przed otrzymaniem odpowiedzi z PHP-FPM. Domyślny limit czasu NGINX wynosi 60 sekund; jeśli zwiększyłeś limit czasu PHP-FPM powyżej 60 sekund, NGINX zwróci błąd limitu czasu bramy 504, jeśli aplikacja PHP nie odpowiedziała w czasie. Możesz temu zapobiec, podnosząc również limit czasu NGINX. W poniższym przykładzie zwiększyliśmy wartość timeoutu do 90 sekund, dodając fastcgi_read_timeout do http blok /etc/nginx/nginx.conf:

nginx.conf

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

Przeładuj konfigurację NGINX, aby zastosować tę zmianę:

Kopiuj
nginx -s reload

następnie, aby ustalić, dlaczego PHP-FPM wygasł, możesz zbierać logi i dane monitorowania wydajności aplikacji (APM), które mogą ujawnić przyczyny opóźnień w aplikacji i poza nią.

Zbieraj i analizuj logi

aby rozwiązać błędy aplikacji, możesz zebrać logi i wysłać je do usługi zarządzania dziennikami. Oprócz dzienników NGINX, które zbadaliśmy powyżej, PHP może rejestrować błędy i inne zdarzenia, które mogą być dla ciebie cenne. Zobacz nasz przewodnik logowania PHP, aby uzyskać więcej informacji.

Po wprowadzeniu logów PHP i NGINX do usługi zarządzania logami, w połączeniu z logami z odpowiednich technologii, takich jak serwery buforujące i bazy danych, możesz analizować logi z całego stosu internetowego na jednej platformie.

wykres słupkowy w Datadog Log Analytics wizualizuje dzienniki PHP i NGINX o różnych statusach, takich jak Błąd, Ostrzeżenie i informacje.
Datadog ’ S Log Analytics pokazuje logi z wielu usług, pogrupowane według stanu.

zbieraj dane APM ze stosu internetowego

APM może pomóc zidentyfikować wąskie gardła i rozwiązać problemy, takie jak błędy 502, które wpływają na wydajność aplikacji. Poniższy zrzut ekranu pokazuje dane APM nginx zwizualizowane w Datadog. Ten widok podsumowuje ilość żądań, liczbę błędów i Opóźnienia dla usługi opartej na NGINX i pomaga zbadać problemy z wydajnością, takie jak błędy 502.

widok usługi Nginx w Datadog APM zawiera wykresy słupkowe pokazujące objętość żądań i błędów, histogram pokazujący rozkład opóźnień i wykres liniowy pokazujący wartości opóźnienia w czasie.

200 OK

im szybciej zdiagnozujesz i rozwiążesz 502 błędy swojej aplikacji, tym lepiej. Datadog pozwala analizować metryki, ślady, dzienniki i dane o wydajności sieci z całej infrastruktury. Jeśli jesteś już klientem Datadog, możesz zacząć monitorować NGINX, PHP-FPM i więcej niż400 innych technologii. Jeśli nie masz jeszcze konta Datadog, Zarejestruj się na 14-dniowy bezpłatny okres próbny i zacznij w kilka minut.