Algoritmos de Equilibrio de Carga Nginx
Nginx proporciona múltiples algoritmos de equilibrio de carga para distribuir tráfico entre servidores upstream basados en diferentes criterios. La selección del algoritmo apropiado depende de los requisitos de su aplicación, estado de sesión, capacidades del servidor y patrones de tráfico. Esta guía cubre todos los algoritmos disponibles, ejemplos de configuración, verificaciones de salud, conexiones keepalive y mejores prácticas.
Tabla de Contenidos
- Descripción General del Equilibrio de Carga
- Algoritmo Round-Robin
- Conexiones Mínimas
- IP Hash
- Algoritmo Aleatorio
- Equilibrio de Carga Ponderado
- Algoritmo Least Time
- Servidores de Respaldo
- Verificaciones de Salud
- Conexiones Keepalive
- Configuración Avanzada
- Monitoreo y Solución de Problemas
Descripción General del Equilibrio de Carga
El equilibrio de carga distribuye solicitudes de cliente entre múltiples servidores backend para mejorar el rendimiento, confiabilidad y utilización de recursos. Nginx evalúa cada solicitud contra los servidores upstream configurados utilizando el algoritmo seleccionado.
Consideraciones clave al elegir un algoritmo:
- Estado de Sesión: Las aplicaciones con estado necesitan enrutamiento consistente (IP hash, cookie)
- Capacidad del Servidor: Los servidores heterogéneos necesitan distribución ponderada
- Patrones de Solicitud: Varían según aplicación (CPU vs I/O intensivo)
- Salud: Los servidores muertos deben detectarse y removerse
- Persistencia: Algunas solicitudes necesitan afinidad a servidores específicos
Algoritmo Round-Robin
Round-robin es el algoritmo predeterminado, distribuyendo solicitudes equitativamente en secuencia:
upstream backend {
server 192.168.1.100:8000;
server 192.168.1.101:8000;
server 192.168.1.102:8000;
}
server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
Distribución de solicitudes con tres servidores:
- Solicitud 1 → Servidor 1
- Solicitud 2 → Servidor 2
- Solicitud 3 → Servidor 3
- Solicitud 4 → Servidor 1
- Y así sucesivamente...
Round-robin es apropiado para servidores homogéneos con capacidad idéntica.
Conexiones Mínimas
El algoritmo de conexiones mínimas enruta solicitudes al servidor manejando actualmente las menos conexiones:
upstream backend {
least_conn;
server 192.168.1.100:8000;
server 192.168.1.101:8000;
server 192.168.1.102:8000;
}
server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://backend;
}
}
Las conexiones mínimas destacan en:
- Aplicaciones con conexiones de larga duración
- Tiempos de procesamiento de solicitud variables
- Equilibrio de carga de conexiones WebSocket
- Aplicaciones en tiempo real con conexiones persistentes
El algoritmo mejora la utilización del servidor enrutando a servidores menos ocupados.
IP Hash
IP hash enruta solicitudes del mismo cliente IP al mismo servidor upstream:
upstream backend {
ip_hash;
server 192.168.1.100:8000;
server 192.168.1.101:8000;
server 192.168.1.102:8000;
}
server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://backend;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
Características de IP hash:
- Asegura afinidad de sesión sin cookies
- Enrutamiento determinístico (misma IP siempre enruta al mismo servidor)
- Útil para aplicaciones con estado que requieren persistencia de sesión
- Reduce misses de caché cuando servidores mantienen cachés locales
Con tres servidores, la función hash enruta consistentemente las solicitudes:
- Cliente 192.168.100.1 → Servidor A
- Cliente 192.168.100.2 → Servidor B
- Cliente 192.168.100.3 → Servidor C
Algoritmo Aleatorio
El algoritmo aleatorio enruta cada solicitud a un servidor upstream seleccionado aleatoriamente:
upstream backend {
random;
server 192.168.1.100:8000;
server 192.168.1.101:8000;
server 192.168.1.102:8000;
}
server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://backend;
}
}
Use random con la opción least_conn para seleccionar entre dos servidores aleatorios:
upstream backend {
random two least_conn;
server 192.168.1.100:8000;
server 192.168.1.101:8000;
server 192.168.1.102:8000;
}
Beneficios de random:
- Distribución simple de carga
- Reducción de hotspot
- Apropiado para aplicaciones sin estado
random two least_connproporciona distribución casi óptima con menor costo de CPU
Equilibrio de Carga Ponderado
Asigne pesos a servidores para reflejar diferentes capacidades:
upstream backend {
server 192.168.1.100:8000 weight=3; # Recibe 3x más solicitudes
server 192.168.1.101:8000 weight=1; # Peso base
server 192.168.1.102:8000 weight=2; # Recibe 2x más solicitudes
}
server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://backend;
}
}
Con estos pesos, la ratio de distribución de solicitudes es 3:1:2:
- De 6 solicitudes: Servidor 1 obtiene 3, Servidor 2 obtiene 1, Servidor 3 obtiene 2
Los pesos funcionan con cualquier algoritmo excepto ip_hash:
upstream backend {
least_conn;
server 192.168.1.100:8000 weight=4;
server 192.168.1.101:8000 weight=2;
}
Algoritmo Least Time
El algoritmo least time selecciona el servidor con tiempo de respuesta promedio mínimo:
upstream backend {
least_time header;
server 192.168.1.100:8000;
server 192.168.1.101:8000;
server 192.168.1.102:8000;
}
Dos variantes:
least_time header: Usa tiempo al primer byteleast_time last_byte: Usa tiempo para completar respuesta
Least time combina métricas de tiempo de respuesta con conteo de conexión para optimizar el rendimiento general.
Servidores de Respaldo
Designe servidores como respaldo, usados solo cuando servidores primarios no están disponibles:
upstream backend {
server 192.168.1.100:8000;
server 192.168.1.101:8000;
server 192.168.1.102:8000 backup;
}
server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://backend;
}
}
El servidor 192.168.1.102 recibe tráfico solo cuando los Servidores 1 y 2 están abajo.
Use múltiples servidores de respaldo:
upstream backend {
server 192.168.1.100:8000 weight=5;
server 192.168.1.101:8000 weight=5;
server 192.168.1.102:8000 weight=2 backup;
server 192.168.1.103:8000 weight=2 backup;
}
Verificaciones de Salud
Las verificaciones de salud pasivas detectan fallos cuando fallan solicitudes:
upstream backend {
server 192.168.1.100:8000 max_fails=3 fail_timeout=30s;
server 192.168.1.101:8000 max_fails=3 fail_timeout=30s;
server 192.168.1.102:8000 max_fails=2 fail_timeout=60s;
}
server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://backend;
proxy_connect_timeout 2s;
proxy_read_timeout 5s;
}
}
Parámetros:
max_fails: Número de fallos antes de marcar abajofail_timeout: Cuánto tiempo esperar antes de reintentarproxy_connect_timeout: Tiempo permitido para conexiónproxy_read_timeout: Tiempo permitido para respuesta
Para verificaciones de salud activas, use el módulo health_checks de Nginx Plus o herramientas de terceros.
Conexiones Keepalive
Habilite HTTP keepalive a servidores upstream para reducir la sobrecarga de conexión:
upstream backend {
server 192.168.1.100:8000;
server 192.168.1.101:8000;
server 192.168.1.102:8000;
keepalive 32;
keepalive_requests 100;
keepalive_timeout 60s;
}
server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
Configuraciones críticas:
keepalive: Número de conexiones inactivas a mantener por upstreamkeepalive_requests: Máximo de solicitudes por conexión (reinicia después)keepalive_timeout: Timeout inactivo antes de cerrarproxy_http_version 1.1: Requerido para keepalive HTTP/1.1proxy_set_header Connection "": Elimina encabezado Connection, habilitando keepalive
Configuración Avanzada
Combine múltiples bloques upstream para escenarios especializados:
upstream fast_api {
least_conn;
server 192.168.1.110:8000;
server 192.168.1.111:8000;
}
upstream slow_api {
server 192.168.1.120:8000;
keepalive 64;
}
upstream static_content {
server 192.168.1.130:80;
keepalive 128;
}
server {
listen 80;
server_name api.example.com;
location /api/v1/ {
proxy_pass http://fast_api;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
location /api/slow/ {
proxy_pass http://slow_api;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_read_timeout 30s;
}
location /static/ {
proxy_pass http://static_content;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
}
Enrutamiento condicional basado en características de solicitud:
upstream api_servers {
least_conn;
server 192.168.1.100:8000;
server 192.168.1.101:8000;
}
upstream mobile_servers {
server 192.168.1.150:8000;
server 192.168.1.151:8000;
}
server {
listen 80;
server_name api.example.com;
set $backend "api_servers";
if ($http_user_agent ~* "mobile|android|iphone") {
set $backend "mobile_servers";
}
location / {
proxy_pass http://$backend;
}
}
Monitoreo y Solución de Problemas
Habilite estadísticas upstream en Nginx:
server {
listen 8080;
location /nginx_status {
stub_status;
access_log off;
allow 127.0.0.1;
deny all;
}
}
Compruebe estado:
curl http://localhost:8080/nginx_status
Verifique la configuración upstream:
nginx -T | grep -A 20 "upstream backend"
Pruebe la conectividad del servidor upstream:
nc -zv 192.168.1.100 8000
curl -v http://192.168.1.100:8000/health
Monitoree los conteos de conexión:
netstat -an | grep ESTABLISHED | wc -l
netstat -an | grep TIME_WAIT | wc -l
Verifique registros de error de Nginx para problemas upstream:
tail -f /var/log/nginx/error.log | grep upstream
Recargue la configuración sin soltar conexiones:
sudo nginx -s reload
sudo systemctl reload nginx
Conclusión
Nginx proporciona algoritmos de equilibrio de carga flexibles y potentes adaptados a requisitos de aplicaciones diversas. Round-robin funciona para servicios sin estado, conexiones mínimas para conexiones persistentes, IP hash para afinidad de sesión y distribución ponderada para infraestructura heterogénea. Combinar estos algoritmos con verificaciones de salud, conexiones keepalive y servidores de respaldo crea configuraciones de equilibrio de carga robustas y resilientes que mantienen alta disponibilidad y rendimiento óptimo.


