Como aumentar os limites de timeout do PHP-FPM e Nginx?

Publicado 13 de outubro de 2024

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:

  1. Abra o arquivo de configuração do PHP-FPM com um editor de texto.
  2. Localize a linha request_terminate_timeout.
  3. Defina o valor em segundos (por exemplo, request_terminate_timeout = 300 para um timeout de 5 minutos).
  4. 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:

  1. Abra o arquivo de configuração do pool (geralmente chamado www.conf).
  2. Localize o parâmetro request_terminate_timeout.
  3. Defina o valor em segundos para esse pool específico.
  4. 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:

  1. Abra seu arquivo de configuração do Nginx (geralmente em /etc/nginx/nginx.conf ou no diretório /etc/nginx/sites-available/).
  2. Encontre o bloco server ou location.
  3. 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:

  1. Encontre o bloco server para o seu site. Geralmente está em um arquivo em /etc/nginx/sites-available/.
  2. 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;
    }
  3. 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:

  1. 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.
  2. 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.
  3. 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
  4. 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:

  1. 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.
  2. 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.

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:

  1. 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.
  2. Logs do Nginx:

    • Revise /var/log/nginx/error.log para erros específicos do Nginx.
    • Use nginx-debug para um registro mais detalhado.
  3. Monitoramento do sistema:

    • Use top ou htop para monitorar recursos do sistema e processos PHP-FPM.
    • Experimente strace para rastrear chamadas de sistema e sinais.

Lidando com Problemas Persistentes de Timeout

Se os problemas de timeout persistirem, investigue estas áreas:

  1. 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.
  2. Chamadas de API externas:

    • Monitore os tempos de resposta de serviços externos.
    • Implemente timeouts para chamadas de API para evitar bloqueios.
  3. 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.
  4. 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:

  1. O uso de recursos atinge consistentemente níveis altos.
  2. As otimizações não melhoram o desempenho.
  3. 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.