⏱️ Lectura: 13 min

Un servidor caído no debería tumbar tu aplicación, y decidir en milisegundos a cuál de los cientos de servidores disponibles enviar cada petición es trabajo de una sola pieza de infraestructura: el load balancer.

📑 En este artículo
  1. TL;DR
  2. Qué es el load balancing y por qué importa
  3. Cómo funciona el load balancing por dentro
    1. Capa 4 vs capa 7
    2. Algoritmos de distribución
    3. Health checks
  4. Ejemplos prácticos: configurar un load balancer real
  5. Cómo empezar paso a paso
  6. Casos de uso reales
  7. Errores comunes y buenas prácticas
  8. Comparativa: algoritmos de balanceo
  9. Profundizando: balanceo avanzado
  10. Preguntas frecuentes
    1. ¿Qué diferencia hay entre load balancing y un proxy reverso?
    2. ¿Necesito load balancing si tengo pocos usuarios?
    3. ¿Round robin es siempre la mejor opción?
    4. ¿Qué pasa si el load balancer mismo se cae?
    5. ¿Nginx o HAProxy?
    6. ¿El load balancing reemplaza a un CDN?
  11. Referencias

Desde el sitio que visitás cada día hasta las APIs detrás de una app bancaria, casi todo el tráfico web pasa primero por un balanceador antes de tocar el servidor que realmente genera la respuesta. Entender cómo funciona ese balanceo es entender cómo escala internet.

TL;DR

  • Vas a entender cómo un load balancer decide a qué servidor enviar cada petición en milisegundos.
  • Vas a poder configurar un balanceador real con Nginx (upstream) y HAProxy (backend) paso a paso.
  • Vas a distinguir round robin, least connections, IP hash y consistent hashing, y cuándo usar cada uno.
  • Vas a saber implementar health checks para sacar servidores caídos de la rotación automáticamente.
  • Vas a diferenciar balanceo de capa 4 (TCP) de capa 7 (HTTP) y por qué la diferencia importa.
  • Vas a identificar los errores comunes que rompen sesiones de usuario al balancear tráfico.
  • Vas a poder verificar con comandos concretos si tu balanceador está enrutando como esperás.

Qué es el load balancing y por qué importa

El load balancing es la técnica de repartir peticiones entrantes entre varios servidores para que ninguno se sature y para que, si uno falla, los demás sigan respondiendo. En vez de exponer un único servidor a internet, exponés una dirección o un dominio que apunta al balanceador, y es él quien decide, petición por petición, hacia dónde reenviar el tráfico.

La razón de fondo es doble: capacidad y disponibilidad. Un solo servidor tiene un techo de CPU, memoria y ancho de banda; sumar réplicas detrás de un balanceador permite crecer horizontalmente sin tocar el código de la aplicación. Y si un servidor se cae, por un despliegue, un crash o un problema de red, el balanceador deja de enviarle tráfico y nadie del lado del cliente nota la diferencia.

Prácticamente toda infraestructura moderna aplica load balancing en más de una capa a la vez: un balanceador de nube reparte tráfico entre zonas de disponibilidad, y dentro de cada zona un Nginx o un HAProxy reparte ese tráfico entre las instancias de la aplicación. En arquitecturas de microservicios, un service mesh como Envoy agrega una tercera capa de balanceo entre los propios servicios internos.

Cómo funciona el load balancing por dentro

Capa 4 vs capa 7

Un balanceador puede operar en capa 4 (transporte, TCP/UDP) o en capa 7 (aplicación, HTTP). Uno de capa 4 mira solo la IP y el puerto de origen y destino: es rápido porque no necesita entender el contenido del paquete, pero no puede decidir según la URL, las cabeceras o las cookies de la petición. Uno de capa 7, en cambio, termina la conexión HTTP, lee la petición completa y puede enrutar /api hacia un grupo de servidores y /static hacia otro, o mandar a un usuario autenticado siempre al mismo backend.

Nginx y HAProxy pueden operar en ambos modos según la configuración; los balanceadores de nube tipo Network Load Balancer trabajan en capa 4, mientras que un Application Load Balancer trabaja en capa 7.

Algoritmos de distribución

El corazón del balanceador es el algoritmo que decide, para cada petición nueva, qué servidor la recibe. Los más comunes son round robin (turnos), least connections (menos conexiones activas), IP hash (la misma IP siempre va al mismo servidor) y consistent hashing, una variante pensada para minimizar el remapeo cuando un servidor se agrega o se cae, la misma técnica detrás de sistemas como Cassandra.

El siguiente diagrama muestra la posición del balanceador entre el cliente y los servidores backend:

flowchart TD
 A["Cliente"] --> B["Load Balancer"]
 B --> C["Servidor 1"]
 B --> D["Servidor 2"]
 B --> E["Servidor 3"]
 subgraph Backend
 C
 D
 E
 end

Health checks

Ningún algoritmo sirve si el balanceador no sabe qué servidores están vivos. Los health checks son peticiones periódicas, un GET a /health por ejemplo, que el balanceador envía a cada servidor backend; si un servidor no responde o responde con error durante varios chequeos seguidos, el balanceador lo saca de la rotación automáticamente y deja de enviarle tráfico hasta que vuelva a responder bien.

Ejemplos prácticos: configurar un load balancer real

Para bajar la teoría a tierra, así se ve el load balancing configurado con las dos herramientas open source más usadas para esto. Este bloque de Nginx define un grupo de tres servidores backend con pesos distintos y balanceo por menor cantidad de conexiones activas:

upstream backend_app {
 least_conn;
 server 10.0.0.11:8080 weight=3;
 server 10.0.0.12:8080 weight=2;
 server 10.0.0.13:8080 backup;
}

server {
 listen 80;
 location / {
 proxy_pass http://backend_app;
 proxy_next_upstream error timeout http_502;
 }
}

least_conn le dice a Nginx que priorice el servidor con menos conexiones abiertas en vez de repartir en turnos ciegos; weight=3 hace que ese servidor reciba proporcionalmente más tráfico que uno con weight=2, y backup marca un servidor que solo recibe tráfico si los otros dos fallan. proxy_next_upstream define en qué casos Nginx reintenta la petición contra otro servidor del grupo en vez de devolver el error al cliente.

HAProxy expresa lo mismo con su propio lenguaje de configuración, y suma un health check HTTP explícito:

frontend http_front
 bind *:80
 default_backend app_servers

backend app_servers
 balance roundrobin
 option httpchk GET /health
 server web1 10.0.0.11:8080 check weight 3
 server web2 10.0.0.12:8080 check weight 2
 server web3 10.0.0.13:8080 check backup

option httpchk GET /health activa el chequeo contra esa ruta en cada servidor; la palabra check en cada línea server habilita ese chequeo puntual, y si el servidor deja de responder con un 200, HAProxy lo saca de rotación sin intervención manual.

Cómo empezar paso a paso

Para probar esto en tu propia máquina no hace falta más que Docker y un par de servidores de prueba.

  1. Instalar HAProxy: apt install haproxy en Debian o Ubuntu, o brew install haproxy en macOS.
  2. Levantar tres servidores de prueba: python3 -m http.server 8080 repetido en tres puertos distintos, o tres contenedores separados.
  3. Pegar la configuración de arriba en /etc/haproxy/haproxy.cfg y reiniciar el servicio con systemctl restart haproxy.
  4. Confirmar que reparte tráfico con varias peticiones seguidas: for i in 1 2 3 4 5 6; do curl -s http://localhost/ | head -1; done.
  5. Apagar uno de los servidores de prueba y repetir el curl en loop para comprobar que el balanceador deja de enviarle tráfico a los pocos segundos.
  6. Habilitar el panel de estadísticas agregando este bloque a la configuración:
listen stats
 bind *:8404
 stats enable
 stats uri /stats

y visitando http://localhost:8404/stats en el navegador, donde cada servidor aparece en verde (UP) o rojo (DOWN) en tiempo real.

Panel de estadísticas de HAProxy mostrando servidores activos y caídos
El panel de stats de HAProxy marca en vivo qué servidor está UP o DOWN. Foto de David Pupăză en Unsplash

Casos de uso reales

El load balancing aparece en capas que rara vez se ven desde afuera. Una aplicación web típica en la nube usa un balanceador de aplicación para repartir tráfico HTTP entre instancias en distintas zonas de disponibilidad, de forma que si una zona entera falla, el resto sigue sirviendo tráfico.

En arquitecturas con base de datos, un balanceador de lectura reparte las consultas SELECT entre varias réplicas mientras las escrituras van siempre al nodo primario; esto es distinto del balanceo de una API, porque acá el criterio no es solo capacidad sino también qué tan actualizada está cada réplica.

A nivel global, el DNS también hace una forma primitiva de balanceo: un mismo dominio puede resolver a varias IPs distintas (DNS round robin), y proveedores de CDN usan Anycast para que la misma IP responda desde el datacenter geográficamente más cercano al usuario, sin que exista un balanceador único centralizado.

Dentro de un clúster de contenedores, Kubernetes expone un Service que balancea internamente entre los pods que respaldan una aplicación, y un service mesh como Envoy agrega una capa extra de balanceo entre los propios servicios internos, con la ventaja de que cada instancia conoce en tiempo real la latencia y el estado de sus vecinos.

Errores comunes y buenas prácticas

  • Ignorar las sesiones con estado: si tu app guarda sesión en memoria local del servidor y el balanceador no usa afinidad por cookie o IP, el usuario pierde su sesión cada vez que una petición cae en un servidor distinto.
  • Health check superficial: un endpoint de salud que solo comprueba que el proceso responde, pero no que puede conectarse a la base de datos, deja servidores vivos pero inútiles dentro de la rotación.
  • Un solo balanceador como punto único de falla: si el balanceador no tiene redundancia propia, activo-pasivo con keepalived o un balanceador de nube gestionado, toda la tolerancia a fallos de los servidores backend no sirve de nada.
  • Timeouts mal calibrados: un timeout demasiado largo hace que el balanceador siga esperando a un servidor lento en vez de reintentar contra otro, arrastrando la lentitud a todos los usuarios.
  • Pesos ignorados en servidores heterogéneos: repartir tráfico en partes iguales entre un servidor con el doble de CPU y uno más chico desperdicia capacidad; ahí es donde weight hace la diferencia.
⚠️ Ojo: un health check que solo responde 200 sin verificar dependencias reales, como base de datos, cache o disco, puede mantener un servidor roto dentro de la rotación durante horas.
Diagrama de un balanceador de carga distribuyendo tráfico entre múltiples servidores
Un balanceador mal configurado puede seguir enviando tráfico a un servidor roto. Foto de Đức Trịnh en Unsplash

Comparativa: algoritmos de balanceo

AlgoritmoCuándo usarloVentajaLimitación
Round RobinServidores con capacidad similarSimple, reparto parejoIgnora la carga real de cada servidor
Least ConnectionsPeticiones de duración variableEvita saturar el servidor más lentoRequiere mantener estado de conexiones activas
IP HashApps con sesión en memoria localEl mismo cliente siempre va al mismo servidorReparto desigual si pocos clientes generan mucho tráfico
WeightedServidores con capacidad distintaAprovecha hardware heterogéneoLos pesos hay que ajustarlos a mano
Consistent HashingClústeres que escalan seguidoMínimo remapeo al agregar o quitar nodosMás complejo de implementar desde cero

Profundizando: balanceo avanzado

Consistent hashing resuelve un problema puntual de IP hash: cuando agregás o quitás un servidor, un hash simple remapea casi todas las claves a servidores distintos, lo que rompe cachés y sesiones en cascada. Consistent hashing distribuye servidores y claves en un mismo anillo, así que agregar o quitar un nodo solo remapea una fracción pequeña del tráfico en vez de todo.

Google publicó su propio algoritmo para este problema, Maglev, pensado para balanceadores de software que manejan millones de conexiones sin mantener tabla de estado por conexión: cada paquete se enruta de forma consistente solo con un hash de sus cabeceras, así que un balanceador puede caerse y otro tomar su lugar sin que las conexiones existentes se corten.

Así se ve, paso a paso, la secuencia de un health check seguida de una petición real:

sequenceDiagram
 participant C as Cliente
 participant LB as Load Balancer
 participant S1 as Servidor A
 participant S2 as Servidor B
 LB->>S1: chequeo de salud
 S1-->>LB: OK 200
 LB->>S2: chequeo de salud
 S2-->>LB: timeout
 Note over LB,S2: Servidor B se marca caído
 C->>LB: solicita página
 LB->>S1: reenvía solicitud
 S1-->>LB: responde datos
 LB-->>C: responde datos

El health check corre en segundo plano, independiente de cualquier petición de usuario; cuando un servidor falla ese chequeo, el balanceador lo saca de la lista de candidatos antes de que un cliente real llegue a tocarlo.

💡 Tip: para confirmar en vivo qué algoritmo está usando tu Nginx, revisá la directiva dentro del bloque upstream con nginx -T | grep -A5 upstream; si no ves least_conn ni ip_hash, está usando round robin por defecto.

📖 Resumen en Telegram: Ver resumen

Tu próximo paso: levantá tres contenedores con un servidor HTTP simple, pegá la configuración de HAProxy de este artículo en /etc/haproxy/haproxy.cfg y mirá el panel de /stats mientras apagás uno de los tres a mano.

Preguntas frecuentes

¿Qué diferencia hay entre load balancing y un proxy reverso?

Un proxy reverso reenvía peticiones a un único backend en nombre del cliente; un load balancer es un proxy reverso que además decide entre varios backends posibles usando un algoritmo de distribución. Todo load balancer HTTP es, técnicamente, un proxy reverso con lógica extra.

¿Necesito load balancing si tengo pocos usuarios?

No por capacidad, pero sí puede convenir por disponibilidad: incluso con poco tráfico, un balanceador con dos servidores idénticos evita que un despliegue o un crash tumben el sitio entero mientras el otro servidor sigue respondiendo.

¿Round robin es siempre la mejor opción?

No. Round robin asume que todas las peticiones cuestan lo mismo y que todos los servidores tienen la misma capacidad; en la práctica eso rara vez es cierto, y least connections o weighted suelen dar mejor resultado.

¿Qué pasa si el load balancer mismo se cae?

Se vuelve un punto único de falla. Por eso en producción se corren al menos dos balanceadores en modo activo-pasivo con una IP virtual compartida (por ejemplo con keepalived), o se usa un balanceador gestionado por el proveedor de nube que ya maneja esa redundancia.

¿Nginx o HAProxy?

Nginx es más común cuando el balanceador también sirve como servidor web o proxy para contenido estático; HAProxy está pensado desde el diseño exclusivamente para balanceo y suele dar más control fino sobre health checks y colas de conexión.

¿El load balancing reemplaza a un CDN?

No, resuelven problemas distintos. Un CDN cachea contenido cerca del usuario para reducir latencia geográfica; un load balancer reparte peticiones entre tus propios servidores de origen. Muchas arquitecturas usan ambos a la vez.

Referencias

📱 ¿Te gusta este contenido? Únete a nuestro canal de Telegram @programacion donde publicamos a diario lo más relevante de tecnología, IA y desarrollo. Resúmenes rápidos, contenido fresco todos los días.

Imagen destacada: Foto de Winston Chen en Unsplash


Javier Alarcón

Ingeniero de infraestructura especializado en redes, sistemas Linux, Kubernetes y arquitecturas cloud. Cubre hardware, networking, observabilidad y prácticas de ingeniería para equipos de producción.

0 Comentarios

Deja un comentario

Marcador de posición del avatar

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.