Como configurar um servidor Nginx de alta performance

1. Fundamentos da otimização do Nginx

O Nginx é um servidor web de alto desempenho baseado em uma arquitetura orientada a eventos e assíncrona. Diferentemente de servidores tradicionais que criam uma thread ou processo por conexão, o Nginx utiliza um modelo de multiplexação que permite gerenciar milhares de conexões simultâneas com baixo consumo de recursos.

Ajuste de processos e conexões worker

O primeiro passo para otimizar o Nginx é configurar adequadamente os parâmetros worker_processes e worker_connections. A regra geral é definir worker_processes igual ao número de núcleos de CPU disponíveis. Para servidores com múltiplos núcleos, isso maximiza a utilização do hardware.

worker_processes auto;  # Ajusta automaticamente para o número de núcleos
events {
    worker_connections 1024;
    use epoll;  # Linux: epoll, FreeBSD: kqueue
    multi_accept on;
}

O valor de worker_connections deve ser calculado com base no limite de arquivos abertos do sistema (ulimit -n). Uma fórmula comum é: worker_connections * worker_processes <= ulimit -n.

Compilação customizada com módulos essenciais

Para ambientes de produção, considerar a compilação do Nginx a partir do código fonte permite incluir apenas os módulos necessários, reduzindo a superfície de ataque e o consumo de memória.

./configure \
    --prefix=/etc/nginx \
    --with-http_ssl_module \
    --with-http_v2_module \
    --with-http_gzip_static_module \
    --with-http_stub_status_module \
    --with-threads \
    --with-file-aio

2. Configuração de cache e compressão

Compressão Gzip dinâmica e estática

A compressão reduz significativamente o tráfego de rede. Ative o gzip com configurações otimizadas para diferentes tipos de conteúdo.

gzip on;
gzip_comp_level 5;
gzip_min_length 256;
gzip_proxied any;
gzip_vary on;
gzip_types
    text/plain
    text/css
    text/javascript
    application/json
    application/javascript
    application/xml+rss
    image/svg+xml;

Para arquivos estáticos pré-compactados, utilize gzip_static para servir arquivos .gz diretamente, evitando compressão em tempo real.

Cache de arquivos estáticos

O open_file_cache reduz operações de disco ao manter metadados de arquivos acessados frequentemente em memória.

open_file_cache max=1000 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;

Proxy cache para respostas de backend

Para aplicações que utilizam proxy reverso, o cache de respostas pode reduzir drasticamente a carga nos servidores de aplicação.

proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=1g inactive=60m;
proxy_cache_key "$scheme$request_method$host$request_uri";

server {
    location /api/ {
        proxy_cache my_cache;
        proxy_cache_valid 200 60m;
        proxy_cache_valid 404 1m;
        proxy_pass http://backend;
    }
}

3. Ajustes de conexão e timeouts

Keepalive e timeouts de conexão

Conexões persistentes reduzem a sobrecarga de handshake TCP, mas devem ser limitadas para evitar esgotamento de recursos.

keepalive_timeout 65;
keepalive_requests 100;
send_timeout 10;
client_body_timeout 12;
client_header_timeout 12;

Ajuste de buffers

Buffers adequados previnem estouro de memória e melhoram o tratamento de requisições grandes.

client_body_buffer_size 128k;
client_header_buffer_size 1k;
large_client_header_buffers 4 8k;
output_buffers 32 32k;
postpone_output 1460;

4. Balanceamento de carga e upstreams

Definição de grupos upstream

Configure grupos de servidores backend com pesos para distribuir a carga conforme a capacidade de cada servidor.

upstream backend {
    least_conn;  # Estratégia: least_connections
    server 192.168.1.10:8080 weight=3;
    server 192.168.1.11:8080 weight=2;
    server 192.168.1.12:8080 backup;
    keepalive 32;
}

Estratégias de balanceamento

  • round-robin (padrão): distribuição sequencial
  • least_connections: envia para o servidor com menos conexões ativas
  • ip_hash: mantém sessões do mesmo cliente no mesmo servidor

Health checks e failover

O Nginx pode detectar servidores indisponíveis e redirecionar o tráfego automaticamente.

upstream backend {
    server 192.168.1.10:8080 max_fails=3 fail_timeout=30s;
    server 192.168.1.11:8080 max_fails=3 fail_timeout=30s;
}

5. Segurança e limitação de tráfego

Limitação de taxa e conexões

Proteja o servidor contra abusos com zonas de limite.

limit_req_zone $binary_remote_addr zone=req_limit:10m rate=10r/s;
limit_conn_zone $binary_remote_addr zone=conn_limit:10m;

server {
    location /login/ {
        limit_req zone=req_limit burst=20 nodelay;
        limit_conn conn_limit 10;
    }
}

Restrições de segurança

Bloqueie métodos HTTP perigosos e cabeçalhos maliciosos.

if ($request_method !~ ^(GET|HEAD|POST)$) {
    return 405;
}

server_tokens off;
more_set_headers "Server: Custom";

Otimização SSL/TLS

Para conexões HTTPS, configure cache de sessão para reduzir o custo de handshake.

ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;

6. Monitoramento e tuning avançado

Logs customizados para análise

Configure logs detalhados para identificar gargalos.

log_format detailed '$remote_addr - $remote_user [$time_local] '
                    '"$request" $status $body_bytes_sent '
                    '"$http_referer" "$http_user_agent" '
                    '$upstream_addr $upstream_response_time $request_time';

access_log /var/log/nginx/access.log detailed;
error_log /var/log/nginx/error.log warn;

Métricas com stub_status

Ative o módulo de status para monitoramento em tempo real.

location /nginx_status {
    stub_status on;
    allow 127.0.0.1;
    deny all;
}

Ajustes de sistema

Otimize os limites do sistema operacional para suportar alta concorrência.

worker_rlimit_nofile 65535;
sendfile on;
tcp_nopush on;
tcp_nodelay on;

7. Testes de carga e validação de performance

Ferramentas de benchmark

Utilize ferramentas especializadas para medir o desempenho.

# Teste com Apache Benchmark
ab -n 10000 -c 100 http://localhost/

# Teste com wrk
wrk -t12 -c400 -d30s http://localhost/

# Teste com httperf
httperf --server localhost --port 80 --num-calls 1000 --rate 100

Análise de gargalos

Verifique a configuração e analise logs para identificar problemas.

nginx -t  # Testa a configuração
tail -f /var/log/nginx/error.log  # Monitora erros

Iteração baseada em métricas

Após cada ajuste, execute testes de carga e compare métricas de throughput (requisições/segundo) e latência (tempo médio de resposta). Ajuste iterativamente até atingir o equilíbrio ideal entre desempenho e uso de recursos.

Referências