¿Qué Es el Balanceo de Carga?
Un balanceador de carga distribuye el tráfico de red entrante entre múltiples servidores para asegurar que ningún servidor individual soporte demasiada carga. Se sitúa entre el cliente y el grupo de servidores, actuando como un proxy inverso que enruta las solicitudes al servidor backend más apropiado.
El balanceo de carga es esencial para lograr alta disponibilidad, fiabilidad y escalabilidad. Sin él, un solo servidor sería un cuello de botella y un punto único de fallo. Con un balanceador de carga, puedes agregar o eliminar servidores del grupo sin ningún tiempo de inactividad, y si un servidor falla, el tráfico se redirige automáticamente a servidores saludables.
Beneficios del Balanceo de Carga
- Alta Disponibilidad: Si un servidor falla, el balanceador de carga deja de enviarle tráfico y redistribuye a servidores saludables.
- Escalabilidad: Agrega más servidores detrás del balanceador de carga para manejar mayor tráfico sin cambiar la configuración del cliente.
- Rendimiento: Distribuye el trabajo uniformemente para evitar que un solo servidor se sature.
- Flexibilidad: Realiza actualizaciones progresivas eliminando servidores uno a la vez, actualizándolos y agregándolos de vuelta.
- Terminación SSL: Descarga el cifrado/descifrado TLS de los servidores backend, reduciendo su carga de CPU.
Algoritmos de Balanceo de Carga
El algoritmo determina cómo el balanceador de carga selecciona qué servidor backend debe manejar cada solicitud entrante. La mejor elección depende de las características de tu carga de trabajo.
1. Round Robin
Las solicitudes se distribuyen secuencialmente entre el grupo de servidores. El Servidor 1 recibe la primera solicitud, el Servidor 2 la segunda, el Servidor 3 la tercera, y así sucesivamente, ciclando de vuelta al Servidor 1 después de llegar al último servidor.
2. Round Robin Ponderado
Como round robin, pero a cada servidor se le asigna un peso basado en su capacidad. Un servidor con peso 3 recibe tres veces más solicitudes que un servidor con peso 1.
3. Menos Conexiones
El balanceador de carga envía cada nueva solicitud al servidor con menos conexiones activas. Esto es más inteligente que round robin porque tiene en cuenta la carga real de cada servidor.
4. Menor Tiempo de Respuesta
Envía solicitudes al servidor con el tiempo de respuesta más rápido y menos conexiones activas. Combina el conteo de conexiones con datos reales de rendimiento.
5. Hash de IP
Un hash de la dirección IP del cliente determina qué servidor recibe la solicitud. Esto asegura que el mismo cliente siempre llegue al mismo servidor, lo cual puede ser útil para la persistencia de sesión.
6. Aleatorio
Selecciona un servidor al azar para cada solicitud. Sorprendentemente efectivo con un gran número de servidores debido a la ley de los grandes números.
Comparación de Algoritmos
| Algoritmo | Complejidad | Sesiones Pegajosas | Mejor Caso de Uso |
|---|---|---|---|
| Round Robin | O(1) | No | Cargas uniformes |
| Round Robin Ponderado | O(1) | No | Capacidades mixtas |
| Menos Conexiones | O(n) | No | Duraciones variables |
| Menor Tiempo de Respuesta | O(n) | No | Apps sensibles a latencia |
| Hash de IP | O(1) | Sí | Afinidad de sesión necesaria |
| Aleatorio | O(1) | No | Grandes grupos de servidores |
Balanceadores L4 vs L7
Los balanceadores de carga operan en diferentes capas del modelo OSI, y la capa determina qué información está disponible para tomar decisiones de enrutamiento.
Balanceo de Capa 4 (Capa de Transporte)
Los balanceadores L4 trabajan a nivel TCP/UDP. Enrutan tráfico basándose en direcciones IP y números de puerto sin inspeccionar el contenido de los paquetes. Son extremadamente rápidos porque no necesitan descifrar TLS ni analizar cabeceras HTTP.
Balanceo de Capa 7 (Capa de Aplicación)
Los balanceadores L7 operan a nivel HTTP/HTTPS. Pueden inspeccionar la solicitud completa — cabeceras, cookies, ruta URL, cuerpo — y tomar decisiones inteligentes de enrutamiento basadas en esta información. Esto habilita capacidades poderosas como enrutamiento basado en ruta, pruebas A/B y despliegues canary.
Cuándo Usar L4 vs L7
- Usa L4 cuando: Necesitas rendimiento bruto y baja latencia (ej. servidores de juegos, conexiones de base de datos, streaming en tiempo real), o cuando no necesitas enrutamiento basado en contenido.
- Usa L7 cuando: Necesitas enrutar basándote en rutas URL (ej. /api a un grupo, /static a otro), necesitas terminación SSL, o requieres funcionalidades avanzadas como pruebas A/B y lanzamientos canary.
Verificaciones de Salud
Las verificaciones de salud son cómo el balanceador de carga sabe si un servidor backend está saludable y capaz de manejar solicitudes. Sin verificaciones de salud, el balanceador de carga podría enviar tráfico a un servidor caído o sobrecargado.
Tipos de Verificaciones de Salud
- Verificación de Salud TCP: Intenta abrir una conexión TCP al servidor. Si la conexión tiene éxito, el servidor se considera saludable.
- Verificación de Salud HTTP: Envía una solicitud HTTP GET a un endpoint específico (ej. /health) y verifica una respuesta 200 OK.
- Verificación de Salud Profunda: El endpoint /health verifica dependencias críticas (base de datos, caché, cola de mensajes) y reporta la salud general del servicio.
// Ejemplo de endpoint de verificación de salud profunda
import express from 'express';
const app = express();
app.get('/health', async (req, res) => {
const checks = {
database: false,
redis: false,
diskSpace: false,
};
try {
await db.query('SELECT 1');
checks.database = true;
} catch (e) {
console.error('Database health check failed:', e);
}
try {
await redis.ping();
checks.redis = true;
} catch (e) {
console.error('Redis health check failed:', e);
}
try {
const freeSpace = await getDiskSpace();
checks.diskSpace = freeSpace > 1_000_000_000;
} catch (e) {
console.error('Disk space check failed:', e);
}
const allHealthy = Object.values(checks).every(Boolean);
res.status(allHealthy ? 200 : 503).json({
status: allHealthy ? 'healthy' : 'unhealthy',
checks,
uptime: process.uptime(),
timestamp: new Date().toISOString(),
});
});
Ejemplos de Configuración de Balanceador de Carga
Configuración de Nginx
Nginx es uno de los balanceadores de carga y proxies inversos de código abierto más populares. Aquí hay una configuración práctica para balanceo de carga HTTP:
upstream backend_servers {
# Algoritmo de menos conexiones
least_conn;
# Servidores backend con verificaciones de salud
server 10.0.1.10:3000 weight=3 max_fails=3 fail_timeout=30s;
server 10.0.1.11:3000 weight=2 max_fails=3 fail_timeout=30s;
server 10.0.1.12:3000 weight=1 max_fails=3 fail_timeout=30s;
# Servidor de respaldo - solo usado cuando todos los demás están caídos
server 10.0.1.13:3000 backup;
# Mantener conexiones vivas a backends
keepalive 32;
}
server {
listen 80;
listen 443 ssl;
server_name api.example.com;
# Configuración SSL
ssl_certificate /etc/ssl/certs/api.example.com.pem;
ssl_certificate_key /etc/ssl/private/api.example.com.key;
# Redirigir HTTP a HTTPS
if ($scheme = http) {
return 301 https://$host$request_uri;
}
location / {
proxy_pass http://backend_servers;
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;
# Timeouts
proxy_connect_timeout 5s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
# Upstream separado para archivos estáticos
location /static/ {
proxy_pass http://static_servers;
proxy_cache static_cache;
proxy_cache_valid 200 1d;
}
}
Configuración de HAProxy
global
maxconn 50000
log stdout format raw local0
defaults
mode http
timeout connect 5s
timeout client 30s
timeout server 30s
option httplog
frontend http_front
bind *:80
bind *:443 ssl crt /etc/ssl/certs/combined.pem
redirect scheme https if !{ ssl_fc }
# Enrutar basado en ruta URL (L7)
acl is_api path_beg /api
acl is_ws hdr(Upgrade) -i websocket
use_backend api_servers if is_api
use_backend ws_servers if is_ws
default_backend web_servers
backend api_servers
balance leastconn
option httpchk GET /health
http-check expect status 200
server api1 10.0.1.10:3000 check inter 10s fall 3 rise 2
server api2 10.0.1.11:3000 check inter 10s fall 3 rise 2
server api3 10.0.1.12:3000 check inter 10s fall 3 rise 2
backend web_servers
balance roundrobin
option httpchk GET /
server web1 10.0.2.10:8080 check
server web2 10.0.2.11:8080 check
backend ws_servers
balance source
server ws1 10.0.3.10:8080 check
server ws2 10.0.3.11:8080 check
Comparación de Herramientas de Balanceo de Carga
| Característica | Nginx | HAProxy | AWS ALB/NLB |
|---|---|---|---|
| Tipo | L4/L7 | L4/L7 | ALB: L7, NLB: L4 |
| Servidor web | Sí | No | No |
| Gestionado | No | No | Sí |
| Terminación SSL | Sí | Sí | Sí |
| WebSocket | Sí | Sí | Sí |
| Costo | Gratis/Código abierto | Gratis/Código abierto | Pago por uso |
Mejores Prácticas
- Siempre configura verificaciones de salud. Sin ellas, un balanceador de carga enviará tráfico a servidores caídos.
- Usa drenado de conexiones. Al eliminar un servidor, permite que las conexiones existentes terminen antes de detener el tráfico.
- Monitorea tu balanceador de carga. Es un componente crítico — si falla, todo lo que está detrás es inalcanzable.
- Haz el balanceador de carga redundante. Usa pares activo-pasivo o activo-activo para evitar un punto único de fallo.
- Usa terminación SSL sabiamente. Termina TLS en el balanceador de carga para reducir la carga de CPU en servidores backend, pero usa conexiones cifradas internamente si manejas datos sensibles.