Como configurar balanceamento de carga com HAProxy

1. Introdução ao HAProxy e Conceitos de Balanceamento

O HAProxy (High Availability Proxy) é um dos softwares mais utilizados para balanceamento de carga e proxy de alta disponibilidade. Ele é amplamente empregado em ambientes de produção para distribuir tráfego entre múltiplos servidores, garantindo maior disponibilidade, escalabilidade e resiliência de aplicações.

O HAProxy suporta diferentes algoritmos de balanceamento, cada um adequado a cenários específicos:
- round-robin: distribui requisições sequencialmente entre os servidores disponíveis
- least connections: envia requisições ao servidor com menos conexões ativas
- source IP: utiliza o hash do IP de origem para direcionar sempre o mesmo cliente ao mesmo servidor

Quanto aos modos de operação, o HAProxy pode atuar em:
- TCP (Layer 4): balanceamento no nível de transporte, encaminhando pacotes sem inspecionar o conteúdo
- HTTP (Layer 7): análise do conteúdo da requisição HTTP, permitindo decisões baseadas em cabeçalhos, cookies ou URI

2. Instalação e Configuração Básica

A instalação do HAProxy varia conforme o sistema operacional. No Ubuntu/Debian:

sudo apt update
sudo apt install haproxy -y

No CentOS/RHEL:

sudo yum install haproxy -y

A estrutura principal de configuração reside no arquivo /etc/haproxy/haproxy.cfg. Um arquivo de configuração mínima possui três seções essenciais:

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

defaults
    log global
    mode http
    option httplog
    timeout connect 5000ms
    timeout client 50000ms
    timeout server 50000ms

frontend http_front
    bind *:80
    default_backend servers_back

backend servers_back
    balance roundrobin
    server web1 192.168.1.10:80 check
    server web2 192.168.1.11:80 check

3. Configuração de Frontend e Backend

O frontend define o ponto de entrada do tráfego. Nele configuramos o IP e a porta de escuta:

frontend web_frontend
    bind 0.0.0.0:80
    option forwardfor
    default_backend web_backend

O backend especifica os servidores de destino e seus parâmetros:

backend web_backend
    balance roundrobin
    server app1 10.0.0.1:8080 check weight 3 maxconn 100
    server app2 10.0.0.2:8080 check weight 2 maxconn 100
    server app3 10.0.0.3:8080 check weight 1 maxconn 100

Parâmetros importantes:
- server: define o nome, endereço e porta do servidor
- check: ativa verificação de saúde
- weight: define prioridade relativa (quanto maior, mais requisições recebe)
- maxconn: limite máximo de conexões simultâneas por servidor

4. Health Checks e Alta Disponibilidade

Os health checks garantem que o tráfego seja direcionado apenas a servidores saudáveis. Configuração avançada:

backend web_backend
    balance roundrobin
    option httpchk GET /health
    server app1 10.0.0.1:8080 check inter 2000 rise 3 fall 2
    server app2 10.0.0.2:8080 check inter 2000 rise 3 fall 2

Parâmetros de verificação:
- inter 2000: intervalo de 2 segundos entre verificações
- rise 3: número de sucessos consecutivos para considerar servidor ativo
- fall 2: número de falhas consecutivas para considerar servidor inativo

Com essa configuração, servidores com falha são automaticamente removidos do pool, garantindo alta disponibilidade sem intervenção manual.

5. Balanceamento com Sticky Sessions (Persistência)

Para aplicações que exigem que um mesmo cliente sempre acesse o mesmo servidor (sessões web), utilizamos persistência:

backend web_backend
    balance roundrobin
    cookie SERVERID insert indirect nocache
    server app1 10.0.0.1:8080 cookie app1 check
    server app2 10.0.0.2:8080 cookie app2 check

Alternativa usando hash de IP de origem:

backend web_backend
    balance source
    hash-type consistent
    server app1 10.0.0.1:8080 check
    server app2 10.0.0.2:8080 check

6. Configuração de Logs e Monitoramento

Para habilitar logs detalhados, configure o syslog:

global
    log /dev/log local0 info
    log /dev/log local1 notice

No arquivo de configuração do rsyslog (/etc/rsyslog.conf):

local0.* /var/log/haproxy.log
local1.* /var/log/haproxy.log

A página de estatísticas fornece monitoramento em tempo real:

frontend stats_front
    bind *:8404
    stats enable
    stats uri /stats
    stats refresh 10s
    stats auth admin:admin123

Acessando http://seu-servidor:8404/stats com credenciais admin/admin123, você visualiza métricas como taxa de requisições, latência, conexões ativas e estado dos servidores.

7. Segurança e Limitação de Tráfego

Para rate limiting, utilizamos stick-tables:

frontend http_front
    bind *:80
    stick-table type ip size 1m expire 30s store http_req_rate(10s)
    http-request track-sc0 src
    http-request deny if { sc_http_req_rate(0) gt 100 }
    default_backend web_backend

Filtragem de IPs (whitelist/blacklist):

frontend http_front
    bind *:80
    acl whitelist src 192.168.1.0/24 10.0.0.0/8
    acl blacklist src 203.0.113.0/24
    http-request deny if blacklist
    http-request allow if whitelist
    default_backend web_backend

Proteção básica contra DDoS com limites de conexão:

frontend http_front
    bind *:80
    maxconn 500
    timeout http-request 10s
    timeout client 30s
    default_backend web_backend

8. Otimização e Boas Práticas

Para alta performance, ajuste os parâmetros de timeout e conexão:

global
    maxconn 10000
    tune.bufsize 32768
    tune.maxrewrite 1024

defaults
    timeout connect 3000ms
    timeout client 30000ms
    timeout server 30000ms
    timeout queue 5000ms
    timeout http-request 5000ms
    timeout http-keep-alive 1000ms

Uso de multi-processamento para melhor utilização de CPU:

global
    nbproc 4
    cpu-map 1 0
    cpu-map 2 1
    cpu-map 3 2
    cpu-map 4 3

Exemplo final de configuração completa com comentários:

global
    log /dev/log local0 info
    maxconn 10000
    user haproxy
    group haproxy
    nbproc 4
    cpu-map 1 0
    cpu-map 2 1
    cpu-map 3 2
    cpu-map 4 3

defaults
    log global
    mode http
    option httplog
    option dontlognull
    retries 3
    timeout connect 5000ms
    timeout client 50000ms
    timeout server 50000ms
    timeout http-request 10s
    timeout queue 1m

# Frontend para tráfego web
frontend web_frontend
    bind *:80
    option forwardfor
    stick-table type ip size 1m expire 30s store http_req_rate(10s)
    http-request track-sc0 src
    http-request deny if { sc_http_req_rate(0) gt 200 }
    acl whitelist src 192.168.1.0/24
    http-request allow if whitelist
    default_backend web_backend

# Frontend para estatísticas
frontend stats_front
    bind *:8404
    stats enable
    stats uri /stats
    stats refresh 10s
    stats auth admin:secure_password

# Backend com servidores web
backend web_backend
    balance leastconn
    option httpchk GET /health
    cookie SERVERID insert indirect nocache
    server web1 10.0.0.1:8080 cookie web1 check inter 2000 rise 3 fall 2 weight 3 maxconn 200
    server web2 10.0.0.2:8080 cookie web2 check inter 2000 rise 3 fall 2 weight 2 maxconn 200
    server web3 10.0.0.3:8080 cookie web3 check inter 2000 rise 3 fall 2 weight 1 maxconn 150 backup

Referências