NGINX 502 Bad Gateway: PHP-FPM
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.
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
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
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:
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
):
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:
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:
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á:
php7.2-fpm.service enabled
Para ver mais informações sobre o PHP-FPM serviço, use este comando:
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:
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
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
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
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
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
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
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
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
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
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:
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.
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.
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.
Leave a Reply