Objetivos de aprendizaje
Después de leer este artículo podrás:
- Entender cómo round robin, least connections, IP hash y hash consistente eligen el servidor
- Elegir el algoritmo correcto para el tipo de tráfico de tu aplicación
- Configurar cada algoritmo en nginx y simular la elección en código
En esta página
- ¿Cuáles son los principales algoritmos de balanceo?
- ¿Cómo funciona el round robin?
- ¿Cómo trata el weighted round robin a servidores distintos?
- ¿Cómo elige el servidor el least connections?
- ¿Cuándo usar IP hash o hash consistente?
- ¿Cómo simular los algoritmos en código?
- ¿Cómo elegir el algoritmo correcto?
- Cómo hacerlo en Square Cloud
- Preguntas frecuentes
Tener varios servidores detrás de un load balancer resuelve solo la mitad del problema. La otra mitad es decidir, en cada petición, a cuál de ellos va. Esa decisión es el algoritmo de balanceo, y cambia la latencia que siente el usuario, cuánto trabaja cada servidor y si una sesión en memoria sobrevive.
Cada algoritmo de abajo viene con su regla de elección, el caso en que falla y su configuración en nginx. Al final, un script corto en Python simula la lógica para que la pruebes.
¿Cuáles son los principales algoritmos de balanceo?#
| Algoritmo | Cómo elige | Punto fuerte | Punto débil |
|---|---|---|---|
| Round robin | Por turnos en orden: 1, 2, 3, 1, 2, 3 | Simple y predecible | Ignora la carga real de cada servidor |
| Weighted round robin | Por turnos en proporción al peso | Servidores de tamaños distintos | Los pesos son fijos, los ajustas a mano |
| Least connections | El servidor con menos conexiones activas | Absorbe peticiones de duración variada | Necesita contar conexiones en tiempo real |
| IP hash | Hash de la IP del cliente | Mismo cliente, mismo servidor | Reparto desigual detrás de un NAT |
| Hash consistente | Hash de una clave (URL, cookie, IP) | Pocas claves cambian de servidor cuando cambia la lista | Más configuración |
| Random con dos opciones | Sortea dos servidores y usa el menos ocupado | Funciona bien con varios balanceadores | Menos intuitivo |
¿Cómo funciona el round robin?#
El round robin es el más simple: el balanceador mantiene un puntero en la lista de servidores y avanza uno en cada petición. Con tres servidores, el orden es 1, 2, 3, 1, 2, 3. No guarda estado sobre los servidores, por eso es barato y no da sorpresas.
Funciona bien cuando los servidores tienen el mismo tamaño y las peticiones cuestan algo parecido. Falla cuando una petición ocupa un servidor durante mucho tiempo: el round robin le sigue mandando trabajo nuevo, porque solo cuenta turnos, no carga.
En nginx es el comportamiento por defecto. La documentación de nginx lo describe como round robin con pesos, y cada servidor tiene peso 1 si no indicas otra cosa.
¿Cómo trata el weighted round robin a servidores distintos?#
Si un servidor tiene el doble de memoria, debería recibir más tráfico. El parámetro weight hace eso. Con pesos 3, 1 y 1, de cada 5 peticiones nuevas, 3 van al primer servidor y 1 a cada uno de los otros:
upstream app {
server 10.0.0.11:3000 weight=3;
server 10.0.0.12:3000;
server 10.0.0.13:3000;
}Los servidores sin weight quedan con el peso por defecto, 1. Es el mismo ejemplo de la documentación de nginx.
¿Cómo elige el servidor el least connections?#
El balanceador lleva la cuenta de cuántas conexiones activas tiene cada servidor y manda la siguiente petición al que tiene menos. Si hay empate, lo resuelve por turnos. En nginx, la directiva tiene en cuenta los pesos de los servidores.
Es la mejor opción cuando la duración de las peticiones varía: subidas de archivos, informes pesados, WebSockets o llamadas a APIs lentas. Un servidor atascado en una petición larga acumula conexiones y deja de recibir nuevas, mientras los demás absorben la cola. Cuando todas las peticiones son cortas e iguales, la ganancia frente al round robin suele ser pequeña.
upstream app {
least_conn;
server 10.0.0.11:3000;
server 10.0.0.12:3000;
server 10.0.0.13:3000;
}¿Cuándo usar IP hash o hash consistente?#
En estos algoritmos la elección depende de una clave, no de la carga. El mismo valor de clave lleva siempre al mismo servidor. Eso sirve para sesiones en memoria, caché local o conexiones que tienen que volver al mismo lugar.
El ip_hash de nginx usa los tres primeros octetos de la IPv4 del cliente (o la IPv6 completa) como clave:
upstream app {
ip_hash;
server 10.0.0.11:3000;
server 10.0.0.12:3000;
server 10.0.0.13:3000 down;
}Hay dos límites. El primero: como solo los tres primeros octetos entran en el hash, los clientes de la misma red /24, y todos los que pasan por el mismo NAT, caen en el mismo servidor, lo que desequilibra la carga. El segundo: si quitas un servidor, el hash se recalcula y muchos clientes cambian de destino. Por eso la documentación indica marcar el servidor retirado temporalmente con down, lo que conserva el mapeo actual.
Para elegir otra clave, como la URL o una cookie, usa hash con consistent. El hash consistente (ketama) garantiza que, al añadir o quitar un servidor, solo una pequeña parte de las claves cambia de destino. Es la opción habitual para cachés, donde reasignarlo todo vaciaría la caché de golpe:
upstream cache {
hash $request_uri consistent;
server 10.0.0.21:8080;
server 10.0.0.22:8080;
server 10.0.0.23:8080;
}¿Existen otros algoritmos?#
Sí. nginx también ofrece random, que sortea un servidor respetando los pesos. La variante random two least_conn sortea dos servidores y se queda con el que tiene menos conexiones activas. Así evita que varios balanceadores independientes manden todo al mismo servidor ocioso al mismo tiempo.
Existe además least_time, que prefiere el servidor con menor tiempo medio de respuesta y menos conexiones. Según la documentación, antes de la versión 1.31.0 era exclusivo de la suscripción comercial (NGINX Plus). Revisa tu versión antes de depender de él.
¿Cómo simular los algoritmos en código?#
Este script en Python 3 implementa round robin, round robin con pesos, least connections y hash por IP. Guárdalo como lb.py y ejecútalo con python lb.py:
import hashlib
import itertools
SERVERS = ["app-1", "app-2", "app-3"]
def round_robin():
return itertools.cycle(SERVERS)
def weighted_round_robin(weights):
# {"app-1": 3, "app-2": 1} se convierte en app-1, app-1, app-1, app-2
return itertools.cycle([s for s, w in weights.items() for _ in range(w)])
def least_connections(active):
# active: conexiones abiertas por servidor; el empate va al primero de la lista
return min(SERVERS, key=lambda s: active[s])
def ip_hash(client_ip):
digest = hashlib.sha256(client_ip.encode()).digest()
return SERVERS[int.from_bytes(digest[:4], "big") % len(SERVERS)]
rr = round_robin()
print([next(rr) for _ in range(6)])
wrr = weighted_round_robin({"app-1": 3, "app-2": 1, "app-3": 1})
print([next(wrr) for _ in range(5)])
print(least_connections({"app-1": 12, "app-2": 3, "app-3": 7}))
print(ip_hash("203.0.113.7") == ip_hash("203.0.113.7"))La salida es ['app-1', 'app-2', 'app-3', 'app-1', 'app-2', 'app-3'], luego ['app-1', 'app-1', 'app-1', 'app-2', 'app-3'], luego app-2 (el menos ocupado) y True (misma IP, mismo servidor). Añade un cuarto servidor a SERVERS y vuelve a ejecutarlo: el ip_hash con módulo reasigna buena parte de los clientes, y eso es justo lo que el hash consistente evita. El weighted round robin de este script manda las tres peticiones seguidas al primer servidor; un balanceador real puede intercalar las elecciones.
¿Cómo elegir el algoritmo correcto?#
- Servidores iguales, peticiones cortas y parecidas: round robin.
- Servidores de tamaños distintos: weighted round robin.
- Peticiones largas o de duración impredecible: least connections.
- Estado en la memoria del servidor que no puedes mover: IP hash. Pero la mejor solución es sacar el estado de la memoria, guardar la sesión en Redis o en una base de datos, y volver a un algoritmo que no dependa de una clave.
- Caché distribuida: hash consistente.
En todos los casos, el balanceo solo funciona si los servidores son intercambiables y el balanceador saca de la rotación a los que fallan. El proxy inverso que está delante de ellos es quien aplica la regla.
Cómo hacerlo en Square Cloud#
En Square Cloud, el balanceo es por dominio. Subes el mismo código a varias aplicaciones y asocias el mismo dominio personalizado a todas; el subdominio squareweb.app no entra en el balanceo. Configuras el dominio creando en tu registrador los registros DNS que muestra el panel (mira cómo usar un dominio personalizado).
El tráfico del dominio se reparte en round robin entre las aplicaciones, con failover pasivo (sin health check activo) si una de ellas deja de estar disponible. No hay cobro por petición. El dominio personalizado empieza en el plan Standard, que permite hasta 2 aplicaciones por dominio. El Pro permite hasta 5 y el Enterprise, hasta 10.
Como el algoritmo es round robin y no hay sticky session, cada petición puede caer en una aplicación distinta, y cada una tiene su propio disco. Guarda las sesiones en una base de datos o en Redis, no en la memoria del proceso. Mira el paso a paso en balanceo de carga.
Red
Dominio propio, TLS automático y CDN global para tu app
Preguntas frecuentes
¿Cuál es el mejor algoritmo de balanceo de carga?
No hay uno mejor para todos los casos. Round robin sirve cuando los servidores y las peticiones son parecidos, least connections cuando la duración de las peticiones varía mucho, e IP hash o hash consistente cuando el mismo cliente tiene que volver al mismo servidor.
¿Qué algoritmo usa nginx por defecto?
Round robin con pesos. Si no declaras ningún método en el bloque upstream, nginx reparte por turnos entre los servidores, y cada uno tiene peso 1 por defecto.
¿Round robin y weighted round robin son distintos?
Sí. En el weighted round robin cada servidor recibe una parte proporcional a su peso. Con pesos 3, 1 y 1, de cada 5 peticiones 3 van al primer servidor.
¿IP hash garantiza una sesión fija?
Casi. La misma IP cae en el mismo servidor mientras la lista de servidores no cambie. Si un servidor entra o sale, parte de los clientes se reasigna, y los clientes detrás del mismo NAT comparten el mismo destino.
Más en Redes y dominios
Ver los 27 artículos- Qué es un balanceador de carga y para qué sirveUn balanceador de carga reparte las solicitudes entre varios servidores. Aprende cómo funciona, los algoritmos, capa 4 y 7 y un ejemplo con nginx.
- Registros DNS: A, CNAME, MX y TXTLos registros DNS son las instrucciones de una zona que indican a dónde apunta un nombre. Entiende A, AAAA, CNAME, MX, TXT, NS y CAA con ejemplos y comandos dig.
- Cómo apuntar un dominio a tu hostingPara apuntar un dominio a tu hosting, crea un registro CNAME (o A) en el DNS de tu registrador. Pasos, cómo comprobarlo y los errores más comunes.
- Encabezado Cache-Control: cuánto tiempo se guarda un archivo en cachéCache-Control es el encabezado HTTP que define cuánto tiempo navegador y CDN guardan una respuesta. Mira max-age, no-cache, immutable y recetas por tipo de archivo.