Articles

NGINX 502 Bad Gateway: PHP-FPM

sugestão / nginx /502 bad gateway /php

nota do Editor: php-fpm usa o termo “mestre” para descrever o seu processo primário. Datadog não usa este termo. Dentro deste post, nós nos referiremos a isso como” primário”, exceto por uma questão de clareza nos casos em que devemos referenciar um nome específico do processo.

Este post faz parte de uma série sobre resolução de problemas NGINX 502 erros de Gateway. Se você não está usando PHP-FPM, confira nosso outro artigo sobre solução de problemas NGINX 502s com Gunicorn como uma infra-estrutura.

PHP-FastCGI Process Manager (PHP-FPM) é um servidor para lidar com pedidos de servidores web para aplicações PHP. Em produção, PHP-FPM é muitas vezes implantado atrás de um servidor web NGINX. NGINX proxies web solicita e passa-os para os processos de trabalhadores PHP-FPM que executam a aplicação PHP.

Um diagrama mostra o fluxo de solicitações do navegador para NGINX para PHP-FPM e volta.

NGINX irá retornar um erro 502 má Gateway se ele não puder obter com sucesso um pedido para PHP-FPM, ou se PHP-FPM não conseguir responder. Neste post, vamos examinar algumas causas comuns de 502 erros na pilha NGINX/PHP-FPM, e vamos fornecer orientação sobre onde você pode encontrar informações que podem ajudá-lo a resolver esses erros.

Explore as métricas, logs, and traces behind NGINX 502 Bad Gateway errors using Datadog.

Algumas possíveis causas de 502s

nesta seção, vamos descrever como as seguintes condições podem causar o NGINX para retornar um erro 502:

  • PHP-FPM não está em execução
  • NGINX não pode se comunicar com o PHP-FPM
  • PHP-FPM é o tempo limite

Se o NGINX é incapaz de se comunicar com o PHP-FPM, por qualquer desses motivos, ele vai responder com um erro 502, observando-o no seu acesso de log (/var/log/nginx/acesso.log) como mostrado neste exemplo:

acesso.log

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

NGINX do log de acesso não explicar a causa de um erro 502, mas você pode consultar o seu erro de log (/var/log/nginx/erro.log) para saber mais. Por exemplo, aqui está uma entrada correspondente no log de erro NGINX que mostra que a causa do erro 502 é que o socket não existe, possivelmente porque o PHP-FPM não está em execução. (Na próxima seção, veremos como detectar e corrigir este problema.)

erro.log

Copy
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 não está em execução

Nota: Esta secção inclui um nome de processo que usa o termo “master”.”Exceto quando se refere a processos específicos, este artigo usa o termo “primário” em vez.

Se o PHP-FPM não estiver em execução, o NGINX irá retornar um erro de 502 para qualquer pedido destinado a alcançar a aplicação PHP. Se você está vendo 502s, primeiro verifique para confirmar que PHP-FPM está funcionando. Por exemplo, em um host Linux, você pode usar um ps comando como este para olhar para executar PHP-FPM processos:

Copiar
sudo ps aux | grep 'php'

PHP-FPM organiza seus processos de trabalho em grupos chamados de piscinas. A saída da amostra abaixo mostra que o processo primário PHP-FPM está em execução, assim como dois processos de trabalho no pool padrão (chamado www):

Copiar
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

Se a saída de ps comando não mostra o PHP-FPM primária ou conjunto de processos, você precisa ter o PHP-FPM correndo para resolver o erro 502 erros.

em um ambiente de produção, você deve considerar usar systemd para executar PHP-FPM como um serviço. Isto pode tornar a sua aplicação de PHP mais fiável e escalável, uma vez que o servidor de PHP-FPM irá automaticamente começar a servir o seu aplicativo de PHP quando o seu servidor começar ou quando uma nova instância for lançada. O PHP-FPM está incluído no código-fonte do PHP, para que possa adicionar o PHP-FPM como um serviço systemd quando configurar o PHP.

uma Vez que o PHP-FPM projeto está configurado como um serviço, você pode usar o seguinte comando para garantir que ele seja iniciado automaticamente quando o servidor é iniciado:

Copiar
sudo systemctl enable php7.2-fpm.service

em Seguida, você pode usar o list-unit-files comando para ver informações sobre o seu serviço:

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

Em PHP 7.2 servidor que tenha o PHP-FPM instalado (mesmo se não estiver em execução), a saída para este comando será:

Copiar
php7.2-fpm.service enabled

Para ver mais informações sobre o PHP-FPM serviço, use este comando:

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

Este comando deve retornar uma saída de active. Se não funcionar, pode começar o serviço com:

Copy
sudo service php7.2-fpm start

NGINX não pode aceder ao ‘socket’

quando o PHP-FPM começa, cria uma ou mais bases TCP ou Unix para comunicar com o servidor web de NGINX. Os processos de trabalhadores do PHP-FPM usam estes sockets para ouvir pedidos da NGINX.

para determinar se um erro 502 foi causado por uma má configuração do socket, confirme que PHP-FPM e NGINX são configurados para usar o mesmo socket. O PHP-FPM utiliza um ficheiro de configuração separado para cada conjunto de processos de trabalhadores; estes ficheiros estão localizados em /etc/php/7.2/fpm/pool.D/. O soquete de cada pool é definido em uma diretrizlisten

no arquivo de configuração do pool. Por exemplo, a diretivalisten

configura um pool chamado mypool para usar um soquete Unix localizado em /run/php/mypool.sock:

mypool.conf

Copiar
listen = /run/php/mypool.sock

Se o NGINX não pode acessar o socket para um determinado pool, você pode determinar qual o conjunto de trabalho é envolvida no problema, verificando que o soquete é chamado no NGINX entrada de log de erro. Por exemplo, se o PHP-FPM não tivesse conseguido iniciar o mypool pool de trabalhadores, o NGINX retornaria um 502 e a sua entrada no registo de erros incluiria:

erro.log

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

Verifique a sua nginx.conf file to ensure that the relevant location block specifies the same socket. O exemplo abaixo contém um include directiva que carrega algumas informações gerais de configuração para o PHP-FPM, e uma fastcgi_pass directiva que especifica o mesmo socket Unix chamado no mypool.ficheiro conf, acima.

nginx.conf

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

as tomadas Unix estão sujeitas a permissões do sistema de Ficheiros Unix. O arquivo de configuração do PHP-FPM pool especifica o modo e a propriedade do socket, como mostrado aqui:

www.conf

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

certifique-se que estas permissões permitem ao utilizador e ao grupo que executa o NGINX aceder ao ‘socket’. Se as permissões no soquete estão incorretas, NGINX registrará um erro 502 em seu log de acesso, e uma mensagem como a mostrada abaixo em seu log de erro:

erro.log

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

Observe que os valores padrão de listen.owner e listen.group corresponde ao padrão de proprietário e de grupo executando o NGINX, e listen.mode predefinições para 0660. Usando estes valores por omissão, NGINX deve ser capaz de acessar o socket.

If PHP-FPM is listening on a TCP socket, the pool conifguration’s listen directive will have a value in the form of address:port, as shown below:

www.conf

Copiar
listen = 127.0.0.1:9000

assim como com um socket Unix, você pode evitar 502 erros confirmando que a localização deste soquete coincide com o especificado no NGINX de configuração.

PHP-FPM está a cronometrar

Se a sua aplicação estiver a demorar muito para responder, os seus utilizadores irão sofrer um erro de tempo-limite. Se o tempo-limite do PHP-FPM-que é definido na configuração do pool ‘s request_terminate_timeout directive (e por omissão é de 20 segundos)—for menor do que o tempo-limite do NGINX (que por omissão é de 60 segundos), o NGINX irá responder com um erro de 502. O log de erro NGINX mostrado abaixo indica que seu processo upstream-que é PHP—FPM-fechou a conexão antes de enviar uma resposta válida. Por outras palavras, este é o registo de erros que vemos quando o PHP-FPM aparece:

erro.log

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

neste caso, o PHP-FPM log (que, por padrão, está localizado em /var/log/php7.2-fpm.log) mostra uma mensagem correlacionada que fornece mais informações:

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

pode aumentar o tempo-limite do PHP-FPM, editando o ficheiro de configuração do pool, Mas isto pode causar outro problema: o NGINX pode sair antes de receber uma resposta do PHP-FPM. O tempo-limite predefinido do NGINX é de 60 segundos; se aumentou o tempo-limite do PHP-FPM acima de 60 segundos, o NGINX irá devolver um erro de tempo-limite do 504 Gateway se a sua aplicação do PHP não tiver respondido a tempo. Você pode evitar isso também aumentando o seu tempo-limite NGINX. No exemplo abaixo, temos levantado o valor de tempo limite de 90 segundos, adicionando o fastcgi_read_timeout item http bloco de /etc/nginx/nginx.conf:

nginx.conf

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

Recarregar seu NGINX de configuração para aplicar esta alteração:

Copy
nginx -s reload

a seguir, para determinar por que o PHP-FPM expirou, pode recolher registos e dados de monitorização do desempenho da aplicação (APM) que podem revelar causas de latência dentro e fora da sua aplicação.

recolher e analisar os seus registos

para resolver erros de aplicação, pode recolher os seus registos e enviá-los para um serviço de gestão de registos. Além dos logs NGINX que examinamos acima, o PHP pode logar erros e outros eventos que podem ser valiosos para você. Veja o nosso guia de Registo PHP para mais informações.

Quando você traz seus logs PHP e NGINX para um serviço de gerenciamento de log, combinado com logs de tecnologias relevantes como servidores de cache e bases de dados, você pode analisar logs de toda a sua pilha web em uma única plataforma.

a bar graph in Datadog Log Analytics visualiza registros de PHP e NGINX de diferentes estados, tais como erro, aviso e info.
Datadog’s Log Analytics shows logs from multiple services, grouped by status.

recolher dados APM da sua pilha web

APM pode ajudá-lo a identificar estrangulamentos e resolver problemas, como os erros 502, que afectam o desempenho da sua aplicação. A imagem abaixo mostra os dados da APM do NGINX visualizados no Datadog. Esta vista resume o volume de Pedidos, taxas de erro e latência para um serviço baseado em NGINX e ajuda você a investigar problemas de desempenho como erros 502.

uma visão de Um NGINX serviço em Datadog APM inclui gráficos de barras mostrando o volume de pedidos e erros, um histograma mostrando a latência de distribuição, e um gráfico de linhas mostrando valores de latência ao longo do tempo.

200 OK

quanto mais rápido você puder diagnosticar e resolver os erros de 502 da sua aplicação, melhor. Datadog permite analisar métricas, traços, logs e dados de desempenho de rede de toda a sua infra-estrutura. Se você já é um cliente Datadog, você pode começar a monitorar NGINX, PHP-FPM e mais de 400 outras tecnologias. Se você ainda não tem uma conta Datadog, Inscreva-se para um teste gratuito de 14 dias e começar em minutos.