// Engineering Log

Servidores proxy: Parte 3 — HAProxy

Publicado el 21.09.2026

HAProxy (High Availability Proxy) — balanceador de carga y proxy inverso para TCP y HTTP de código abierto. A diferencia de nginx, HAProxy no sirve archivos ni ejecuta el código de las aplicaciones: su tarea es aceptar conexiones, repartirlas entre servidores, vigilar el estado de los servidores y aplicar reglas al tráfico. Además de la versión libre, la empresa HAProxy Technologies publica la versión comercial HAProxy Enterprise.

Las ramas con número par tienen soporte a largo plazo (LTS) durante cinco años. A septiembre de 2026 las ramas LTS vigentes son 3.2 (publicada en mayo de 2025) y 3.4 (junio de 2026). Para servidores en producción conviene usar la versión LTS desde el repositorio de la distribución o los paquetes oficiales para ella.

Conceptos básicos de la configuración

La configuración se guarda en /etc/haproxy/haproxy.cfg y consta de secciones:

  • global — parámetros del proceso: logging, usuario, límite de conexiones;
  • defaults — valores por defecto para las demás secciones: modo, timeouts;
  • frontend — dónde HAProxy acepta conexiones: dirección, puerto, certificado, reglas;
  • backend — grupo de servidores, algoritmo de balanceo y comprobaciones de estado;
  • listen — atajo que combina frontend y backend.

El modo de funcionamiento se define con la directiva mode: http — HAProxy analiza solicitudes HTTP y puede tomar decisiones por ruta, cabeceras y cookies; tcp — pasa la conexión completa sin inspeccionarla, apropiado para cualquier protocolo sobre TCP.

Ejemplo: sitio HTTPS en tres servidores

haproxy
global
    log /dev/log local0
    maxconn 20000
    user haproxy
    group haproxy

defaults
    mode http
    log global
    option httplog
    timeout connect 5s
    timeout client  30s
    timeout server  30s
    timeout tunnel  1h

frontend web
    bind :80
    bind :443 ssl crt /etc/haproxy/certs/example.ru.pem alpn h2,http/1.1
    http-request redirect scheme https unless { ssl_fc }
    http-request set-header X-Forwarded-Proto https if { ssl_fc }
    option forwardfor
    default_backend app

backend app
    balance roundrobin
    option httpchk
    http-check send meth GET uri /health ver HTTP/1.1 hdr Host example.ru
    http-check expect status 200
    server app1 10.0.0.11:3000 check inter 3s fall 3 rise 2
    server app2 10.0.0.12:3000 check inter 3s fall 3 rise 2
    server app3 10.0.0.13:3000 check inter 3s fall 3 rise 2 backup

Explicación:

  • en el archivo example.ru.pem el certificado, los certificados intermedios y la clave privada se almacenan juntos en un único archivo;
  • alpn h2,http/1.1 activa HTTP/2 para los clientes;
  • option forwardfor añade la cabecera X-Forwarded-For con la dirección del cliente;
  • timeout tunnel 1h define la vida de las conexiones tras pasar a WebSocket; sin ello se cerrarían por timeout client y timeout server;
  • balance roundrobin envía las peticiones por turno. Otras opciones: leastconn — al servidor con menos conexiones (adecuado para conexiones largas), source — una IP cliente siempre al mismo servidor.

Comprobación y aplicación de la configuración:

bash
haproxy -c -f /etc/haproxy/haproxy.cfg && systemctl reload haproxy

Comprobaciones de estado de los servidores

La principal diferencia de HAProxy respecto a nginx gratuito son las comprobaciones activas: HAProxy consulta periódicamente cada servidor y no espera a que las peticiones de usuarios lleguen a un servidor caído. En el ejemplo anterior se envía un GET /health cada 3 segundos. Tras tres comprobaciones fallidas consecutivas (fall 3) el servidor se excluye del balanceo; tras dos correctas (rise 2) vuelve a entrar. Un servidor con la etiqueta backup recibe tráfico solo cuando los servidores principales están indisponibles.

Tipos de comprobaciones:

  • TCP — solo establecimiento de conexión; se activa con check sin option httpchk;
  • HTTP — petición a una ruta de comprobación con código de respuesta o contenido esperado;
  • comprobaciones de protocolos — integradas para MySQL, PostgreSQL, Redis, SMTP, LDAP y el saludo TLS;
  • agente — en el servidor corre un pequeño programa que informa a HAProxy de su carga o pide temporalmente salir del balanceo.

HAProxy no tiene comprobaciones por ICMP (ping), además eso no indicaría si la aplicación funciona. Lo más útil es una comprobación HTTP a una ruta /health que la aplicación atiende solo si la base de datos y otras dependencias están disponibles.

Afinidad del usuario al servidor

Si la aplicación guarda la sesión en la memoria del proceso, el usuario debe llegar siempre al mismo servidor. HAProxy puede insertar él mismo una cookie con el nombre del servidor:

haproxy
backend app
    balance roundrobin
    cookie SERVERID insert indirect nocache
    server app1 10.0.0.11:3000 check cookie app1
    server app2 10.0.0.12:3000 check cookie app2

Si un servidor deja de estar disponible, el usuario se redirigirá a otro y perderá la sesión. Es más fiable almacenar las sesiones en un almacén compartido y no ligar usuarios a servidores.

Limitación de la tasa de solicitudes: stick-tables

Stick-table — tabla en la memoria de HAProxy que guarda contadores por clave, por ejemplo por dirección IP del cliente. Sobre ella se construyen límites de tasa:

haproxy
frontend web
    bind :443 ssl crt /etc/haproxy/certs/example.ru.pem alpn h2,http/1.1
    stick-table type ipv6 size 1m expire 10m store http_req_rate(10s)
    http-request track-sc0 src
    http-request deny deny_status 429 if { sc_http_req_rate(0) gt 100 }
    default_backend app

Un cliente que envíe más de 100 solicitudes en 10 segundos recibe un 429. El tipo ipv6 almacena también direcciones IPv4. Esas mismas tablas se usan para contabilizar errores por cliente, limitar el número de conexiones simultáneas y para intercambiar contadores entre dos instancias de HAProxy (sección peers).

Modo TCP: balanceo de PostgreSQL

haproxy
frontend postgres
    mode tcp
    bind :5432
    default_backend pg_servers

backend pg_servers
    mode tcp
    balance leastconn
    option pgsql-check user haproxy
    server pg1 10.0.0.21:5432 check
    server pg2 10.0.0.22:5432 check backup

option pgsql-check comprueba que PostgreSQL responde al conectar con el usuario haproxy (debe existir en la base). HAProxy no sabe cuál de los servidores es el primario y cuál la réplica de solo lectura. En clústeres con conmutación automática, por ejemplo Patroni, se dirige la comprobación al interfaz HTTP de Patroni, que responde con código 200 solo en el servidor primario.

Página de estadísticas

haproxy
frontend stats
    mode http
    bind 127.0.0.1:8404
    stats enable
    stats uri /stats
    stats refresh 10s
    stats auth admin:надёжный-пароль

En la página se ve el estado de cada servidor, el número de conexiones, errores y tiempos de respuesta. No conviene exponerla a Internet: en el ejemplo escucha solo la dirección local y es accesible vía túnel SSH. Para sistemas de monitorización HAProxy ofrece métricas en formato Prometheus (http-request use-service prometheus-exporter).

Caché

HAProxy tiene caché de respuestas en memoria. Está pensado para objetos pequeños y muy consultados, por ejemplo respuestas de una API: el volumen total está limitado a 4095 MB, y el tamaño de un solo objeto a la mitad de ese volumen. Para cachear archivos grandes y páginas con mucho contenido es más apropiado nginx con caché en disco, por eso a menudo se usan juntos.

Alta disponibilidad del propio HAProxy

El balanceador elimina el punto único de fallo entre los servidores de la aplicación, pero él mismo puede convertirse en ese punto. Normalmente se despliegan dos HAProxy con la misma configuración y una IP virtual compartida que gestiona keepalived (protocolo VRRP): si el nodo principal deja de responder, la dirección pasa en segundos al de respaldo.

Gestión sin reinicio

A través del socket de control (Runtime API) se puede consultar el estado y sacar servidores de servicio sin cambiar la configuración. En la sección global se añade:

haproxy
    stats socket /run/haproxy/admin.sock mode 660 level admin

Después de esto, por ejemplo, antes de actualizar un servidor se lo pone en modo mantenimiento y luego se lo vuelve a dejar activo:

bash
echo "set server app/app1 state maint" | socat stdio /run/haproxy/admin.sock
echo "set server app/app1 state ready" | socat stdio /run/haproxy/admin.sock
echo "show stat" | socat stdio /run/haproxy/admin.sock

En modo mantenimiento HAProxy no envía nuevas solicitudes al servidor. Así se actualiza la aplicación uno a uno sin tiempo de inactividad para los usuarios.

Registros

HAProxy escribe registros vía syslog. Con option httplog cada línea contiene la dirección del cliente, el frontend, backend y servidor seleccionados, el código de respuesta, el tamaño y los timings: cuánto tiempo la petición estuvo en cola, cuánto se tardó en establecer la conexión con el servidor y cuánto tardó el servidor en preparar la respuesta. Con esos campos es fácil localizar dónde se produce la latencia: en la red, en la cola o en la propia aplicación.

Fortalezas y debilidades

Ventajas:

  • comprobaciones de estado activas en la versión libre;
  • funciona tanto con HTTP como con cualquier tráfico TCP;
  • estadísticas y métricas detalladas;
  • stick-tables para límites y contabilización de clientes;
  • cambio de estado de servidores en caliente vía Runtime API (socket de control) sin reinicio.

Desventajas:

  • no sirve archivos estáticos ni ejecuta aplicaciones;
  • la caché está limitada a objetos pequeños en memoria;
  • la sintaxis de la configuración y la lógica de las reglas requieren tiempo para dominarse.

Se elige HAProxy cuando la tarea principal es repartir la carga entre varios servidores y sacar rápidamente de servicio a los que fallan. Para un único servidor con un sitio normalmente basta con nginx.

// Contact

¿Necesitas ayuda?

Escríbeme y te ayudaré a resolver el problema

Respondo en un día laborable (03:00-13:00 GMT)

Или оставьте заявку здесь:

Confirme que no es un bot.

Escribir y recibir una respuesta rápida