Proxy Reverso e Load Balancing
Aula 2 de 6
Proxy Reverso com proxy_pass
Configuração Básica
server {
listen 80;
server_name app.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;
}
}
proxy_set_header - Cabeçalhos Essenciais
location / {
proxy_pass http://localhost:8080;
# Cabeçalhos padrão de proxy
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;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
# Suprimir cabeçalhos indesejados
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
Proxy para Múltiplos Backends
# Proxy diferentes caminhos para diferentes backends
server {
listen 80;
server_name api.exemplo.com;
location / {
proxy_pass http://localhost:3000;
}
location /api/ {
proxy_pass http://localhost:8080/api/;
}
location /admin/ {
proxy_pass https://admin.internal:8443/;
proxy_ssl_verify on;
proxy_ssl_trusted_certificate /etc/nginx/ssl/internal-ca.crt;
}
location /static/ {
root /var/www/public;
expires 1y;
}
}
Upstream e Load Balancing
Configuração de Upstream
upstream backend_cluster {
# Método de balanceamento
# round-robin (padrão), least_conn, ip_hash, random, hash
# Servidores do cluster
server backend1.exemplo.com:8080 weight=3;
server backend2.exemplo.com:8080 weight=2;
server backend3.exemplo.com:8080 weight=1 backup;
# Health check (Nginx Plus)
# zone backend 64k;
# health_check interval=5 fails=3 passes=2;
}
server {
listen 80;
server_name load.exemplo.com;
location / {
proxy_pass http://backend_cluster;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
Métodos de Balanceamento
# Round-Robin (padrão)
upstream backend {
server 10.0.0.1:8080;
server 10.0.0.2:8080;
server 10.0.0.3:8080;
}
# Least Connections
upstream backend {
least_conn;
server 10.0.0.1:8080;
server 10.0.0.2:8080;
server 10.0.0.3:8080;
}
# IP Hash (sessões persistentes)
upstream backend {
ip_hash;
server 10.0.0.1:8080;
server 10.0.0.2:8080;
server 10.0.0.3:8080;
}
# Hash genérico (por query string, cookie, etc.)
upstream backend {
hash $request_uri consistent;
server 10.0.0.1:8080;
server 10.0.0.2:8080;
server 10.0.0.3:8080;
}
# Random (distribuição uniforme)
upstream backend {
random two least_conn;
server 10.0.0.1:8080;
server 10.0.0.2:8080;
server 10.0.0.3:8080;
}
Flags de Servidor no Upstream
upstream backend {
# Peso maior = mais requisições
server 10.0.0.1:8080 weight=5;
# Backup: só recebe requisições se os principais falharem
server 10.0.0.2:8080 backup;
# Down: marca como offline (sem remover do config)
server 10.0.0.3:8080 down;
# max_fails/fail_timeout: quantas falhas até marcar como down
server 10.0.0.4:8080 max_fails=3 fail_timeout=30s;
# Slow start (Nginx Plus): ramp up gradual
server 10.0.0.5:8080 slow_start=30s;
}
Health Checks
Passive Health Checks (open source)
upstream backend {
server 10.0.0.1:8080 max_fails=3 fail_timeout=30s;
server 10.0.0.2:8080 max_fails=3 fail_timeout=30s;
# Proxy timeouts para detectar falhas mais rápido
proxy_connect_timeout 5s;
proxy_read_timeout 10s;
proxy_send_timeout 10s;
}
Active Health Checks (Nginx Plus)
upstream backend {
zone backend 64k;
server 10.0.0.1:8080;
server 10.0.0.2:8080;
health_check interval=5 fails=3 passes=2;
health_check uri=/health;
health_match expected 200;
}
Buffers e Timeouts
location / {
proxy_pass http://backend;
# Tamanho dos buffers
proxy_buffer_size 4k;
proxy_buffers 8 4k;
proxy_busy_buffers_size 8k;
# Desabilitar buffer para streaming
proxy_buffering off;
# Aumentar buffers para respostas grandes
proxy_buffer_size 8k;
proxy_buffers 16 8k;
proxy_busy_buffers_size 16k;
proxy_max_temp_file_size 0;
# Timeouts
proxy_connect_timeout 10s; # Conexão com backend
proxy_read_timeout 30s; # Esperando resposta
proxy_send_timeout 30s; # Enviando requisição
# Tamanho máximo do corpo
client_max_body_size 100m;
client_body_buffer_size 128k;
}
WebSocket Proxy
# Mapeamento para upgrade de conexão
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80;
serverName ws.exemplo.com;
# Proxy HTTP normal
location / {
proxy_pass http://app_backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# Proxy WebSocket
location /ws {
proxy_pass http://ws_backend:8080;
# Headers obrigatórios para WebSocket
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
# Timeouts longos para WebSocket
proxy_read_timeout 86400s;
proxy_send_timeout 86400s;
}
}
Lab: Cluster com Proxy Reverso
Configure um proxy reverso com balanceamento de carga para uma aplicação Node.js.
# 1. Criar aplicação Node.js de exemplo
sudo mkdir -p /opt/app
cat << 'APP' | sudo tee /opt/app/server.js
const http = require('http');
const os = require('os');
const port = process.env.PORT || 3000;
http.createServer((req, res) => {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end(`Servidor: ${os.hostname()} | Porta: ${port}\n`);
}).listen(port, () => {
console.log(`Servidor rodando na porta ${port}`);
});
APP
# 2. Iniciar múltiplas instâncias
cd /opt/app
node server.js &
PORT=3001 node server.js &
PORT=3002 node server.js &
# 3. Criar configuração de upstream
cat << 'NGINX' | sudo tee /etc/nginx/sites-available/cluster
upstream app_cluster {
least_conn;
server 127.0.0.1:3000 max_fails=3 fail_timeout=10s;
server 127.0.0.1:3001 max_fails=3 fail_timeout=10s;
server 127.0.0.1:3002 max_fails=3 fail_timeout=10s;
}
server {
listen 80;
server_name cluster.local;
location / {
proxy_pass http://app_cluster;
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_connect_timeout 5s;
proxy_read_timeout 10s;
proxy_buffering off;
# Health check endpoint
location /health {
proxy_pass http://app_cluster;
access_log off;
return 200 "OK\n";
}
}
# WebSocket support
location /ws/ {
proxy_pass http://app_cluster;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 3600s;
}
access_log /var/log/nginx/cluster-access.log;
error_log /var/log/nginx/cluster-error.log;
}
NGINX
# 4. Habilitar e testar
sudo ln -sf /etc/nginx/sites-available/cluster /etc/nginx/sites-enabled/
sudo rm -f /etc/nginx/sites-enabled/default
# 5. Testar configuração
sudo nginx -t && sudo systemctl reload nginx
# 6. Testar balanceamento
for i in {1..6}; do
curl -s http://cluster.local
done
# 7. Simular falha de um servidor
kill $(lsof -ti:3001)
# 8. Verificar se o health check removeu o servidor
for i in {1..3}; do
curl -s http://cluster.local
done
Proxy reverso com Nginx vai além de redirecionar tráfego: ele adiciona resiliência com health checks, escalabilidade com load balancing, e performance com buffers e timeouts bem ajustados. Sempre configure cabeçalhos X-Forwarded-* para que o backend conheça o IP real do cliente.