Problema: Limites de Timeout do PHP-FPM e Nginx
Os limites de timeout no PHP-FPM e Nginx podem causar problemas ao processar scripts longos ou lidar com uploads de arquivos grandes. Essas configurações padrão podem levar a timeouts de conexão, resultando em operações inacabadas e mensagens de erro para os visitantes do site.
Configurando as Definições de Timeout do PHP-FPM
Modificando o Arquivo de Configuração do PHP-FPM
O arquivo de configuração do PHP-FPM geralmente está em /etc/php/[versão]/fpm/php-fpm.conf
. Para alterar as configurações de timeout, modifique o parâmetro request_terminate_timeout
. Este parâmetro define o tempo máximo que um script pode ser executado antes que o PHP-FPM o interrompa.
Para definir este parâmetro:
- Abra o arquivo de configuração do PHP-FPM com um editor de texto.
- Localize a linha
request_terminate_timeout
. - Defina o valor em segundos (por exemplo,
request_terminate_timeout = 300
para um timeout de 5 minutos). - Se a linha estiver ausente, adicione-a ao arquivo.
Dica: Faça Backup Antes de Editar
Antes de fazer alterações no arquivo de configuração do PHP-FPM, crie um backup. Isso permite que você reverta as alterações, se necessário. Use este comando:
sudo cp /etc/php/[versão]/fpm/php-fpm.conf /etc/php/[versão]/fpm/php-fpm.conf.backup
Ajustando as Configurações do Pool do PHP-FPM
Os pools do PHP-FPM são grupos de processos PHP que lidam com solicitações. Cada pool pode ter sua própria configuração, incluindo configurações de timeout. Os arquivos de configuração do pool geralmente estão em /etc/php/[versão]/fpm/pool.d/
.
Para modificar as configurações de timeout específicas do pool:
- Abra o arquivo de configuração do pool (geralmente chamado
www.conf
). - Localize o parâmetro
request_terminate_timeout
. - Defina o valor em segundos para esse pool específico.
- Se o parâmetro estiver ausente, adicione-o ao arquivo.
Configurando as Definições de Timeout do Nginx
Configurando o Timeout Fastcgi do Nginx
A diretiva fastcgi_read_timeout
controla quanto tempo o Nginx espera o PHP-FPM processar uma solicitação. Essa configuração ajuda a prevenir erros 504 Gateway Timeout quando os scripts demoram para serem executados.
Para definir o fastcgi_read_timeout
no Nginx:
- Abra seu arquivo de configuração do Nginx (geralmente em
/etc/nginx/nginx.conf
ou no diretório/etc/nginx/sites-available/
). - Encontre o bloco server ou location.
- Adicione ou altere a diretiva
fastcgi_read_timeout
:fastcgi_read_timeout 300s;
Isso define o timeout para 300 segundos (5 minutos).
Dica: Ajuste o Timeout com Base nos Requisitos do Script
Considere as necessidades específicas da sua aplicação ao definir o fastcgi_read_timeout
. Para scripts que processam grandes quantidades de dados ou realizam operações complexas, pode ser necessário aumentar esse valor. Monitore o desempenho da sua aplicação e ajuste conforme necessário.
Modificando o Bloco Server do Nginx
Para aplicar as configurações de timeout, modifique o bloco server na sua configuração do Nginx:
- Encontre o bloco server para o seu site. Geralmente está em um arquivo em
/etc/nginx/sites-available/
. - Localize o bloco de localização de processamento PHP, que geralmente se parece com isso:
location ~ \.php$ { fastcgi_pass unix:/var/run/php/php7.4-fpm.sock; fastcgi_index index.php; include fastcgi_params; }
- Adicione as configurações de timeout a este bloco de localização:
location ~ \.php$ { fastcgi_pass unix:/var/run/php/php7.4-fpm.sock; fastcgi_index index.php; include fastcgi_params; fastcgi_read_timeout 300s; }
Implementando a Solução
Guia Passo a Passo para Aumentar os Limites de Timeout
Para aumentar os limites de timeout do PHP-FPM e Nginx, siga estes passos:
-
Edite a configuração do PHP-FPM:
- Abra o arquivo de configuração do pool PHP-FPM (
/etc/php/[versão]/fpm/pool.d/www.conf
) com um editor de texto. - Adicione ou altere o parâmetro
request_terminate_timeout
:request_terminate_timeout = 300
- Salve o arquivo.
- Abra o arquivo de configuração do pool PHP-FPM (
-
Altere as configurações do Nginx:
- Abra seu arquivo de configuração do Nginx (
/etc/nginx/nginx.conf
ou/etc/nginx/sites-available/
). - Encontre o bloco server para o seu site.
- Adicione ou atualize a diretiva
fastcgi_read_timeout
no bloco de localização de processamento PHP:location ~ \.php$ { fastcgi_pass unix:/var/run/php/php7.4-fpm.sock; fastcgi_index index.php; include fastcgi_params; fastcgi_read_timeout 300s; }
- Salve o arquivo.
- Abra seu arquivo de configuração do Nginx (
-
Reinicie os serviços para aplicar as alterações:
- Reinicie o PHP-FPM:
sudo systemctl restart php7.4-fpm
- Reinicie o Nginx:
sudo systemctl restart nginx
- Reinicie o PHP-FPM:
-
Teste a nova configuração:
- Execute um script que leve mais tempo que o timeout padrão para garantir que ele seja concluído sem erros.
- Verifique seus logs de erro em busca de problemas relacionados a timeout.
Solução de Problemas Comuns
Verificando as Alterações de Configuração
Para verificar se suas novas configurações foram aplicadas:
-
Verifique a configuração do PHP-FPM:
- Execute
php-fpm -tt
para testar o arquivo de configuração em busca de erros de sintaxe. - Use
php -i | grep max_execution_time
para verificar a configuração de tempo máximo de execução.
- Execute
-
Verifique a configuração do Nginx:
- Execute
nginx -t
para testar a configuração do Nginx em busca de erros de sintaxe. - Use o comando
curl -I
para verificar os cabeçalhos de resposta e ver se as novas configurações de timeout estão refletidas.
- Execute
Dica: Verifique a Configuração do Pool PHP-FPM
Para verificar se a configuração do seu pool PHP-FPM está correta, use o seguinte comando:
php-fpm -d --fpm-config=/etc/php-fpm.d/www.conf
Este comando exibirá quaisquer erros de configuração no seu arquivo de pool.
Ferramentas de depuração para PHP-FPM e Nginx:
-
Logs do PHP-FPM:
- Verifique
/var/log/php-fpm/error.log
para problemas relacionados ao PHP-FPM. - Habilite o log lento na configuração do PHP-FPM para rastrear scripts lentos.
- Verifique
-
Logs do Nginx:
- Revise
/var/log/nginx/error.log
para erros específicos do Nginx. - Use
nginx-debug
para um registro mais detalhado.
- Revise
-
Monitoramento do sistema:
- Use
top
ouhtop
para monitorar recursos do sistema e processos PHP-FPM. - Experimente
strace
para rastrear chamadas de sistema e sinais.
- Use
Lidando com Problemas Persistentes de Timeout
Se os problemas de timeout persistirem, investigue estas áreas:
-
Consultas de banco de dados:
- Verifique consultas lentas usando o log de consultas lentas do banco de dados.
- Otimize índices e estrutura de consultas do banco de dados.
-
Chamadas de API externas:
- Monitore os tempos de resposta de serviços externos.
- Implemente timeouts para chamadas de API para evitar bloqueios.
-
Operações no sistema de arquivos:
- Verifique E/S de disco lenta usando ferramentas como
iotop
. - Considere mudar para soluções de armazenamento mais rápidas, se necessário.
- Verifique E/S de disco lenta usando ferramentas como
-
Uso de memória:
- Monitore o uso de memória PHP com ferramentas como New Relic ou Blackfire.
- Aumente o limite de memória PHP se os scripts estiverem atingindo o limite.
Considere escalonamento de servidor ou otimização de código quando:
- O uso de recursos atinge consistentemente níveis altos.
- As otimizações não melhoram o desempenho.
- O crescimento do tráfego supera a capacidade atual do servidor.
Para otimização de código:
- Use ferramentas de perfil para identificar gargalos.
- Refatore o código para melhorar a eficiência.
- Implemente estratégias de cache para reduzir o tempo de processamento.
Para escalonamento de servidor:
- Considere o escalonamento vertical (aumentando os recursos do servidor).
- Explore o escalonamento horizontal (adicionando mais servidores).
- Considere soluções de balanceamento de carga para distribuir o tráfego.
Exemplo: Implementando Cache para Melhoria de Desempenho
Para reduzir o tempo de processamento e melhorar o desempenho, implemente o cache Redis:
<?php
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$key = 'user_data_' . $user_id;
$cached_data = $redis->get($key);
if ($cached_data === false) {
// Dados não estão no cache, buscar do banco de dados
$data = fetchUserDataFromDatabase($user_id);
// Armazenar no cache para uso futuro
$redis->set($key, serialize($data), 3600); // Cache por 1 hora
} else {
$data = unserialize($cached_data);
}
Este exemplo mostra como implementar o cache Redis para armazenar e recuperar dados do usuário, reduzindo a carga do banco de dados e melhorando os tempos de resposta.