NGINX: Guia Prático - Proxy Reverso, Load Balancer e Cache HTTP
Aprenda a usar NGINX para resolver problemas reais: proxy reverso, balanceamento de carga, cache HTTP, SSL termination e rate limiting com exemplos práticos.
O que é NGINX e por que usar
NGINX é um servidor web e proxy reverso de alta performance. Criado em 2004 por Igor Sysoev para lidar com o problema C10K (10.000 conexões simultâneas), hoje é usado por mais de 30% dos sites do mundo.
Diferenciais principais:
- Arquitetura assíncrona e baseada em eventos: consome menos memória que servidores tradicionais (Apache modo prefork).
- Alta performance: lida com milhares de conexões com pouco overhead.
- Versatilidade: funciona como web server, proxy reverso, load balancer, cache HTTP e gateway de API.
Principais problemas que NGINX resolve
1. Proxy Reverso
Um proxy reverso intercepta requisições HTTP do cliente e as encaminha para servidores backend. Isso permite esconder a topologia interna, adicionar segurança e centralizar logs.
Exemplo básico de proxy reverso
server {
listen 80;
server_name exemplo.com;
location / {
proxy_pass http://localhost:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Este bloco redireciona tráfego de exemplo.com para uma aplicação rodando em localhost:3000 (ex.: Node.js, Spring Boot).
2. Load Balancer (Balanceamento de Carga)
Distribui requisições entre múltiplos servidores backend para aumentar disponibilidade e escalabilidade.
Exemplo com round-robin
upstream backend {
server 192.168.1.10:8080;
server 192.168.1.11:8080;
server 192.168.1.12:8080;
}
server {
listen 80;
server_name exemplo.com;
location / {
proxy_pass http://backend;
}
}
Algoritmos de balanceamento
- round-robin: distribui sequencialmente (padrão).
- least_conn: envia para o servidor com menos conexões ativas.
- ip_hash: garante que o mesmo IP sempre vá para o mesmo servidor (útil para sessões).
Exemplo com least_conn e health check
upstream backend {
least_conn;
server 192.168.1.10:8080 max_fails=3 fail_timeout=30s;
server 192.168.1.11:8080 max_fails=3 fail_timeout=30s;
server 192.168.1.12:8080 backup;
}
Aqui, max_fails define quantas falhas consecutivas desativam temporariamente o servidor. O servidor marcado como backup só recebe requisições se os outros caírem.
3. Cache HTTP
NGINX pode cachear respostas de servidores backend para reduzir latência e carga no banco de dados.
Configuração de cache
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=1g inactive=60m;
server {
listen 80;
server_name exemplo.com;
location / {
proxy_cache my_cache;
proxy_cache_valid 200 60m;
proxy_cache_valid 404 10m;
proxy_cache_key "$scheme$request_method$host$request_uri";
add_header X-Cache-Status $upstream_cache_status;
proxy_pass http://backend;
}
}
Agora respostas HTTP 200 ficam cacheadas por 60 minutos. O header X-Cache-Status mostra se a resposta veio do cache (HIT) ou do backend (MISS).
4. SSL/TLS Termination
NGINX pode lidar com criptografia HTTPS e enviar requisições HTTP simples para o backend, aliviando a carga de processamento nos servidores de aplicação.
Exemplo com Let's Encrypt
server {
listen 443 ssl http2;
server_name exemplo.com;
ssl_certificate /etc/letsencrypt/live/exemplo.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/exemplo.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
location / {
proxy_pass http://localhost:3000;
proxy_set_header X-Forwarded-Proto https;
}
}
server {
listen 80;
server_name exemplo.com;
return 301 https://$host$request_uri;
}
O bloco na porta 80 redireciona automaticamente para HTTPS. O backend recebe requisições HTTP simples.
5. Rate Limiting
Protege APIs e aplicações contra abuso, limitando a taxa de requisições por IP ou chave customizada.
Exemplo de rate limit
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;
server {
listen 80;
server_name api.exemplo.com;
location /api/ {
limit_req zone=api_limit burst=20 nodelay;
proxy_pass http://backend;
}
}
Aqui cada IP pode fazer no máximo 10 requisições por segundo. O burst permite picos temporários de até 20 requisições antes de rejeitar.
6. Compressão Gzip
Reduz o tamanho das respostas HTTP, melhorando performance para usuários com conexões lentas.
Exemplo de gzip
server {
listen 80;
server_name exemplo.com;
gzip on;
gzip_vary on;
gzip_min_length 256;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml;
location / {
root /var/www/html;
index index.html;
}
}
7. Servir Conteúdo Estático
NGINX é extremamente eficiente para servir arquivos estáticos (HTML, CSS, JS, imagens) sem precisar passar pelo backend.
Exemplo de server block para SPA (React, Vue, Angular)
server {
listen 80;
server_name app.exemplo.com;
root /var/www/app/dist;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
location /assets/ {
expires 1y;
add_header Cache-Control "public, immutable";
}
}
O try_files garante que todas as rotas do SPA retornem o index.html. Arquivos em /assets/ ficam cacheados por 1 ano.
Casos de uso reais
Microservices Gateway
Use NGINX como API Gateway para rotear requisições entre microserviços:
upstream auth_service {
server 192.168.1.10:8001;
}
upstream orders_service {
server 192.168.1.11:8002;
}
server {
listen 80;
server_name api.exemplo.com;
location /auth/ {
proxy_pass http://auth_service/;
}
location /orders/ {
proxy_pass http://orders_service/;
}
}
Blue-Green Deployment
Altere o upstream para fazer deployment sem downtime:
upstream backend {
server blue.internal:8080; # versão atual
# server green.internal:8080; # nova versão (comentada)
}
# Para fazer deploy: troque para green, recarregue (nginx -s reload), valide e remova blue
Monitoramento e Debug
Status Module (NGINX Plus ou stub_status)
server {
listen 8080;
location /nginx_status {
stub_status;
allow 127.0.0.1;
deny all;
}
}
Logs personalizados
log_format custom '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'rt=$request_time uct="$upstream_connect_time" '
'uht="$upstream_header_time" urt="$upstream_response_time"';
access_log /var/log/nginx/access.log custom;
Isso inclui tempos de resposta do backend nos logs, facilitando troubleshooting.
Boas práticas
- Use HTTP/2: adicione
http2na diretivalisten 443 ssl http2;. - Ative keep-alive:
keepalive_timeout 65;reduz overhead de conexões. - Configure timeouts:
proxy_read_timeout,proxy_connect_timeoutevitam requisições travadas. - Proteja configurações sensíveis: use
deny all;para bloquear acesso a endpoints internos. - Teste antes de aplicar:
nginx -tvalida a sintaxe. Depoisnginx -s reloadaplica sem downtime.
Comandos essenciais
# Testar configuração
nginx -t
# Recarregar sem downtime
nginx -s reload
# Ver logs em tempo real
tail -f /var/log/nginx/access.log
tail -f /var/log/nginx/error.log
# Parar NGINX
nginx -s stop
# Verificar se o processo está rodando
ps aux | grep nginx
Conclusão
NGINX é uma ferramenta versátil que resolve problemas críticos de infraestrutura: proxy reverso, balanceamento de carga, cache, SSL termination e rate limiting. Com as configurações deste guia, você pode implementar soluções robustas em produção.
Comece com configurações simples, teste em ambiente local (Docker, Vagrant) e evolua conforme as necessidades de carga e segurança. NGINX tem documentação oficial excelente e comunidade ativa, então qualquer dúvida específica pode ser resolvida consultando nginx.org/en/docs/.
FAQ
NGINX é melhor que Apache?
Depende do caso. NGINX é mais eficiente para alto volume de conexões e conteúdo estático. Apache tem mais módulos e é mais flexível para aplicações legadas. Para proxies e load balancers, NGINX geralmente vence.
Posso usar NGINX como WAF (Web Application Firewall)?
Sim, com o módulo ModSecurity. Mas soluções dedicadas (Cloudflare, AWS WAF) são mais completas.
Como escalar NGINX em produção?
Use múltiplas instâncias atrás de um load balancer (ex.: AWS ALB, Google Cloud Load Balancer) ou rode NGINX em Kubernetes com réplicas.
NGINX Plus vale a pena?
Se você precisa de features enterprise (health checks ativos, API para configuração dinâmica, suporte oficial), sim. Caso contrário, a versão open-source resolve a maioria dos casos.
Qual a diferença entre upstream e proxy_pass?
upstream define um grupo de servidores. proxy_pass direciona a requisição para um upstream ou URL específica.