Resolução de Problemas de Nginx 504 Gateway Timeout e Timeout do Cliente
Nginx, embora conhecido por seu alto desempenho e estabilidade, pode, às vezes, apresentar erros frustrantes, mais notavelmente códigos de status HTTP indicando uma falha na comunicação. Entre os mais comuns estão o 504 Gateway Timeout e vários timeouts do lado do cliente. Esses problemas quase sempre resultam de uma incompatibilidade entre o tempo que o Nginx espera por uma resposta de um serviço de backend (como um servidor de aplicação ou outro proxy) e o tempo que o cliente (navegador ou serviço upstream) está disposto a esperar pelo próprio Nginx.
Este guia abrangente o guiará pelo diagnóstico da causa raiz desses timeouts e fornecerá ajustes de configuração concretos para resolver erros 504 e melhorar a estabilidade geral da conexão. Compreender esses mecanismos é crucial para manter a alta disponibilidade, especialmente em arquiteturas de microsserviços ou ao lidar com aplicações upstream de resposta lenta.
Compreendendo o Erro 504 Gateway Timeout
Um erro 504 Gateway Timeout ocorre quando o Nginx, atuando como um proxy reverso ou gateway, não recebe uma resposta oportuna do servidor upstream para o qual está encaminhando as requisições. Em termos simples: o Nginx pediu uma resposta ao backend, esperou pelo tempo configurado e desistiu porque nenhuma resposta chegou.
Isso é distinto de um 502 Bad Gateway (que implica uma resposta inválida do upstream) ou um 503 Service Unavailable (que implica que o upstream está atualmente sobrecarregado ou indisponível).
Diretivas Chave para Controlar Upstream Timeouts
Ao realizar o proxy de requisições, o Nginx usa várias diretivas críticas, localizadas principalmente dentro dos blocos http, server ou location, ou especificamente dentro de um bloco upstream. Ajustar esses valores é o método principal para resolver erros 504.
1. proxy_connect_timeout
Isso define o timeout para estabelecer uma conexão com o servidor upstream. Se o Nginx não conseguir conectar-se dentro desse período, ele retorna um erro de timeout.
Padrão: 60 segundos
proxy_connect_timeout 60s;
2. proxy_send_timeout
Isso define o timeout para o tempo entre duas operações de escrita sucessivas para o servidor upstream. Isso é relevante ao enviar um corpo de requisição grande.
Padrão: 60 segundos
proxy_send_timeout 60s;
3. proxy_read_timeout (A Correção Mais Comum para 504s)
Isso define o timeout para aguardar uma resposta do servidor upstream depois que os cabeçalhos da requisição foram enviados. Se a aplicação de backend demorar muito para processar a requisição e gerar um corpo de resposta, esta é a diretiva que precisa ser aumentada.
Padrão: 60 segundos
# Exemplo: Aumentando o timeout de leitura para 120 segundos para uma API lenta
proxy_read_timeout 120s;
Boa Prática: Se sua aplicação frequentemente excede o padrão de 60 segundos, aumente este valor com cautela. Um valor muito alto pode mascarar problemas fundamentais de desempenho do backend.
Lidando com Timeouts do Lado do Cliente
Enquanto o 504 se relaciona com a comunicação Nginx-para-Backend, os timeouts do lado do cliente ocorrem quando o cliente (por exemplo, um navegador, aplicativo móvel ou outro serviço fazendo uma requisição para o Nginx) desiste de esperar antes mesmo que o Nginx tenha terminado de se comunicar com o backend.
Se você está experimentando timeouts do cliente antes que o Nginx registre um 504, você precisa analisar a conexão entre o cliente e o Nginx.
1. Keepalive do Lado do Cliente
Se o cliente fechar a conexão prematuramente, o Nginx pode receber um erro ou o cliente pode simplesmente atingir o timeout esperando por dados.
Certifique-se de que as configurações de conexão do lado do cliente (se configuráveis) não sejam muito agressivas. Se o cliente for outro proxy ou balanceador de carga, verifique suas configurações de timeout em relação ao send_timeout do Nginx.
2. send_timeout do Nginx
Esta diretiva controla por quanto tempo o Nginx esperará que o cliente confirme ou receba dados (o tempo entre duas operações de escrita sucessivas para o cliente).
Padrão: 60 segundos
# Defina isso se os clientes estiverem atingindo o timeout enquanto o Nginx está enviando a resposta
send_timeout 120s;
Otimizando o Buffering para Respostas Grandes
Às vezes, os timeouts ocorrem não porque o processamento demorou muito, mas porque o Nginx começou a armazenar a resposta do upstream em buffer e falhou em completar a escrita do buffer antes que a conexão atingisse o timeout. Isso é particularmente relevante ao lidar com respostas muito grandes.
O Nginx usa buffers para armazenar temporariamente dados recebidos do upstream antes de enviá-los ao cliente. Se a resposta for muito grande, esses buffers podem ser excedidos, levando a um tratamento complexo ou latência percebida.
Diretivas Chave de Buffering
Estas são geralmente definidas dentro do bloco location ou server:
| Diretiva | Propósito |
|---|---|
proxy_buffers |
Define o número e o tamanho dos buffers usados para ler o cabeçalho da resposta do upstream. Formato: número tamanho; |
proxy_buffer_size |
Define o tamanho do primeiro buffer, que é usado para ler o cabeçalho da resposta. |
proxy_max_temp_file_size |
Se a resposta exceder os buffers disponíveis, o Nginx escreve em arquivos temporários. Isso define o tamanho máximo para esses arquivos temporários. |
Exemplo de Configuração para Grandes Volumes/Respostas Grandes:
location /api/heavy_report {
proxy_pass http://backend_app;
# Aumentar o timeout de leitura
proxy_read_timeout 180s;
# Ajustar o buffering para corpos de resposta potencialmente grandes
# Usar 8 buffers, cada um de até 1MB (1024k)
proxy_buffers 8 1024k;
proxy_buffer_size 256k;
# Permitir arquivos temporários de até 500MB se os buffers estourarem
proxy_max_temp_file_size 500m;
}
Dica sobre Buffering: Se sua resposta de backend for realmente enorme (por exemplo, vários GBs), considere servir conteúdo estático ou implementar streaming diretamente, pois o buffering de respostas extremamente grandes pode consumir uma memória significativa no servidor Nginx.
Etapas de Resolução de Problemas e Análise de Logs
Resolver timeouts requer identificar onde o atraso ocorreu: Cliente -> Nginx, ou Nginx -> Backend.
Passo 1: Verificar os Logs de Erro do Nginx
O log de erro do Nginx é sua fonte definitiva para determinar se o Nginx atingiu o timeout esperando pelo backend.
Procure por entradas contendo frases como:
upstream timed out (110: Connection timed out)upstream prematurely closed connection while reading response header from upstream
Se você vir essas, o problema reside no proxy_read_timeout ou no tempo de processamento do backend.
Passo 2: Verificar os Logs da Aplicação Backend
Se o Nginx atingir o timeout (os logs indicam 504), verifique imediatamente os logs do serviço upstream (por exemplo, logs do PHP-FPM, logs do Gunicorn, logs do servidor de aplicação Java). Você precisa confirmar se a requisição sequer chegou ao backend e quanto tempo levou para ser concluída.
- Se os logs do backend mostrarem que a requisição levou mais tempo do que o seu
proxy_read_timeoutconfigurado, aumente o timeout do Nginx. - Se os logs do backend mostrarem que a requisição foi concluída rapidamente, o problema pode ser latência de rede entre o Nginx e o backend, ou um timeout de cliente mal configurado voltado para o Nginx.
Passo 3: Usar o Cabeçalho X-Upstream-Response-Time (Opcional)
Para diagnósticos detalhados, você pode registrar o tempo exato que o upstream levou para responder usando a variável $upstream_response_time no formato do seu log de acesso. Isso ajuda a confirmar o desempenho real do backend.
No seu nginx.conf:
log_format proxy_detailed '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" $request_time $upstream_response_time';
access_log /var/log/nginx/access.log proxy_detailed;
Ao analisar $upstream_response_time, você pode ver a duração precisa que o Nginx esperou, independentemente das configurações de timeout do próprio Nginx.
Resumo e Aplicação de Mudanças
Resolver problemas de timeout do Nginx geralmente envolve um ato de equilíbrio entre as expectativas do cliente e as capacidades de processamento do backend. Lembre-se da relação:
- 504 Timeout: O backend está muito lento ou o link de rede falhou enquanto o Nginx esperava (
proxy_read_timeout). - Timeout do Cliente: O cliente desistiu de esperar pelo Nginx (
send_timeoutou configuração do cliente).
Após fazer quaisquer alterações de configuração (por exemplo, aumentar timeouts ou ajustar tamanhos de buffer), sempre teste a sintaxe da configuração e recarregue o Nginx:
sudo nginx -t
sudo systemctl reload nginx
Monitore cuidadosamente seus logs após aplicar as correções, pois aumentar cegamente os timeouts pode mascarar gargalos de desempenho subjacentes do sistema que exigem otimização em vez de soluções alternativas de configuração.