Ajuste de Buffer do Nginx: Otimizando client_body_buffer_size e proxy_buffer_size
O Nginx é renomado por seu alto desempenho, eficiência e escalabilidade, frequentemente servindo como um robusto proxy reverso, balanceador de carga ou servidor web. Um aspecto crítico para alcançar o desempenho máximo reside na configuração correta de seus mecanismos internos de buffer. Os buffers ditam como o Nginx lida com os corpos de requisição de entrada (para uploads ou dados POST) e respostas do upstream de saída. A configuração incorreta pode levar a um consumo excessivo de memória ou, inversamente, a lentas operações de I/O em disco, anulando as vantagens de velocidade do Nginx.
Este guia mergulha profundamente nas diretivas de buffer principais — client_body_buffer_size, proxy_buffer_size, e configurações relacionadas — explicando sua função, impacto e fornecendo passos acionáveis para ajustá-las de acordo com sua carga de trabalho específica. O ajuste eficaz do buffer previne a troca desnecessária de dados para o disco, melhorando diretamente a latência de resposta e o throughput geral.
Entendendo os Fundamentos do Buffer do Nginx
O Nginx usa buffers para armazenar temporariamente dados que fluem através de seus processos, seja dados de um cliente para o servidor, ou do servidor para uma aplicação backend upstream.
Quando um buffer é preenchido, o Nginx deve decidir se continua o buffer na memória ou se despeja o excesso de dados em um arquivo temporário no disco. O I/O de disco é significativamente mais lento que o acesso à memória, portanto, o objetivo do ajuste é garantir que os tamanhos típicos de requisição/resposta caibam confortavelmente nos buffers de memória.
Visão Geral das Diretivas de Buffer Principais
Várias diretivas controlam o buffering, muitas vezes dependendo do contexto (comunicação com cliente, proxying ou FastCGI):
client_body_buffer_size: Controla o tamanho do buffer usado para ler o corpo da requisição do cliente (usado em requisições POST, uploads de arquivos, etc.).proxy_buffer_size: Controla o tamanho do buffer usado para ler respostas de um servidor upstream ao atuar como proxy reverso.proxy_buffers: Define o número e o tamanho dos buffers usados para ler respostas do servidor upstream quando os dados excedemproxy_buffer_size.fastcgi_buffer_sizeefastcgi_buffers: Diretivas semelhantes específicas para comunicação FastCGI (ex: PHP-FPM).
Ajustando client_body_buffer_size
Esta diretiva é crucial quando o Nginx lida diretamente com grandes uploads ou submissões de formulário extensas.
Comportamento Padrão e Impacto
Por padrão, o Nginx geralmente define client_body_buffer_size para um valor relativamente pequeno (frequentemente 8k ou 16k, dependendo da versão). Se o corpo da requisição do cliente exceder este tamanho, o Nginx começa a escrever os dados excedentes em um arquivo temporário no disco (client_body_temp_path).
Impacto: Se você antecipa lidar com requisições maiores que o tamanho de buffer padrão, mas menores que a sua RAM disponível permite, aumentar este valor pode prevenir escritas lentas no disco.
Exemplo de Configuração
A diretiva é definida nos contextos http, server ou location:
http {
# Define o tamanho do buffer para corpos de requisição do cliente para 128KB
client_body_buffer_size 128k;
...
}
Melhor Prática: Defina este valor com base no tamanho típico máximo dos dados POST que você espera, e não no tamanho máximo absoluto de upload permitido. Se você o definir muito alto globalmente, e muitos clientes enviarem requisições moderadamente grandes simultaneamente, você corre o risco de consumir memória excessiva em todos os processos de worker.
Otimizando Buffers de Proxy Reverso: proxy_buffer_size e proxy_buffers
Quando o Nginx atua como um proxy reverso, a principal preocupação muda para o buffer da resposta que retorna do servidor upstream (ex: Apache, Tomcat ou uma aplicação Node.js).
proxy_buffer_size
Define o tamanho do buffer inicial usado para ler o cabeçalho da resposta e o primeiro bloco do corpo da resposta do servidor upstream.
proxy_buffers (Número e Tamanho)
Se o corpo da resposta do upstream for grande, o Nginx usa um conjunto de buffers definidos por proxy_buffers. Esta diretiva aceita dois argumentos:
- O número de buffers.
- O tamanho de cada buffer.
Se os dados da resposta excederem o espaço total de buffer alocado (Número * Tamanho), o Nginx começará a escrever os dados restantes no disco no diretório proxy_temp_path.
Exemplo de Configuração (Contexto Proxy)
Para garantir que grandes respostas de um servidor upstream permaneçam na memória, você pode configurar os buffers do proxy da seguinte forma:
location /api/ {
proxy_pass http://backend_servers;
# Define o tamanho inicial do buffer para 64k
proxy_buffer_size 64k;
# Usa 8 buffers, cada um com 128k de tamanho, para o restante da resposta.
# Capacidade total do buffer: 8 * 128k = 1MB
proxy_buffers 8 128k;
# Define o tamanho máximo que pode ser escrito temporariamente no disco antes que o Nginx comece a enviar dados para o cliente
proxy_max_temp_file_size 10m;
}
Dica: Se o seu backend tipicamente retorna grandes payloads JSON ou arquivos estáticos grandes, investigue o tamanho típico da resposta e defina proxy_buffers grande o suficiente para cobrir 95% dessas respostas. Você pode precisar aumentar proxy_buffer_size se o servidor upstream enviar cabeçalhos de resposta grandes.
Gerenciando o Despejo para Disco (proxy_max_temp_file_size)
Se o Nginx ficar sem espaço de buffer de memória (conforme definido por proxy_buffers ou client_body_buffer_size), ele despeja o excesso para o disco. A diretiva que controla quando isso acontece é *_temp_file_size.
Por padrão, o Nginx permite que arquivos temporários cresçam indefinidamente, o que pode consumir espaço em disco rapidamente sob alta carga.
proxy_max_temp_file_size
Isto limita o tamanho do arquivo temporário que o Nginx pode criar ao armazenar em buffer respostas upstream. Definir isso como 0 desabilita totalmente o uso de arquivos temporários, forçando o Nginx a armazenar em buffer na memória ou retornar um erro (ou fechar a conexão, dependendo do contexto) se o buffer for excedido.
# Exemplo: Se o buffer exceder a memória, pare de escrever no disco após 20MB
proxy_max_temp_file_size 20m;
# Exemplo: Desabilita completamente o despejo para disco (use com cautela e RAM suficiente)
proxy_max_temp_file_size 0;
Aviso sobre proxy_max_temp_file_size 0: Embora elimine o I/O de disco, se seus processos de worker lidarem com inúmeras requisições concorrentes que excedam o espaço total de buffer alocado, você pode enfrentar erros de esgotamento de memória ou fechamentos de conexão inesperados se o Nginx não conseguir processar o fluxo de dados.
Ajustando Buffers FastCGI (fastcgi_buffer_size)
Para aplicações que se comunicam via FastCGI (como PHP), a lógica de buffer é semelhante, mas usa diretivas dedicadas.
fastcgi_buffer_size define o tamanho do buffer para ler o cabeçalho e a parte inicial da resposta FastCGI. fastcgi_buffers define o array de buffers usados para ler os dados do corpo subsequentes.
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
# Define os buffers FastCGI para 16 buffers de 16k cada
fastcgi_buffers 16 16k;
# Se a resposta for muito grande, ajuste o tamanho
fastcgi_buffer_size 128k;
}
Resumo e Estratégia de Ajuste
O ajuste eficaz do buffer é um ato de equilíbrio entre a disponibilidade de memória do sistema e as características da carga de trabalho.
- Analise a Carga de Trabalho: Determine o tamanho típico dos corpos de requisição do cliente e das respostas upstream.
- Corpo do Cliente: Defina
client_body_buffer_sizepara cobrir o tamanho típico maior de dados POST/upload. - Respostas do Proxy: Defina
proxy_buffers(contagem e tamanho) grandes o suficiente para acomodar a maioria das respostas de backend na RAM. - Limite o Despejo: Use
proxy_max_temp_file_sizepara limitar o uso de disco resultante de estouros de buffer, ou defina-o como0somente se você tiver certeza de que sua alocação de memória é suficiente.
Lembre-se de testar o desempenho minuciosamente após as alterações de configuração e monitorar a utilização da memória do sistema.
# Após alterar o nginx.conf, sempre teste a sintaxe antes de recarregar
nginx -t
# Em seguida, recarregue o Nginx para aplicar as alterações sem derrubar as conexões
systemctl reload nginx