O HAProxy, operando na camada de aplicação (camada 7), oferece recursos avançados de balanceamento de carga através de suas regras de Access Control List (ACL). Essas regras permitem a criação de sistemas de balanceamento de carga dinâmicos e inteligentes.
As ACLs no HAProxy servem a dois propósitos principais:
- Validação de Requisições: Verificar se uma requisição do cliente atende aos critérios definidos. Requisições que não cumprem as regras são imediatamente descartadas.
- Direcionamento Inteligente: Encaminhar requisições que satisfazem as regras ACL para servidores backend específicos, implementando assim o balanceamento de carga baseado em critérios definidos.
As regras ACL são comumente configuradas na seção frontend do HAProxy.
A sintaxe básica para definir uma ACL é:
acl nome_da_acl metodo [-i] [critério_de_correspondência]
acl: Palavra-chave que inicia a definição de uma regra ACL, seguida por um nome customizado para a regra.metodo: Define o tipo de verificação a ser realizada. O HAProxy oferece diversos métodos, incluindo:hdr_reg(host): Correspondência de domínio/hostname usando expressões regulares.hdr_dom(host): Correspondência exata de domínio/hostname (sem regex).hdr_beg(host): Correspondência de domínio/hostname que começa com um prefixo específico.url_sub: Busca por uma substring dentro da URL da requisição.url_dir: Verifica se a URL contém uma string específica como parte do caminho.path_beg: Verifica se o caminho da URL começa com uma string específica.path_end: Verifica se o caminho da URL termina com uma string específica.- E muitos outros.
-i: Indica que a correspondência deve ser insensível a maiúsculas e minúsculas.critério_de_correspondência: O valor a ser comparado com a requisição (por exemplo, um nome de domínio, uma string na URL ou uma expressão regular).
Juntamente com as ACLs, o parâmetro use_backend é fundamental. Ele especifica qual cluster de servidores backend (backend) deve receber a requisição caso uma ACL seja satisfeita. O parâmetro default_backend define o destino padrão quando nenhuma ACL é acionada.
Exemplos de Regras ACL
A seguir, alguns exemplos práticos:
# Regra: www_policy. Corresponde a domínios que começam com 'www.z.cn' ou 'z.cn'.
acl www_policy hdr_reg(host) -i ^(www.z.cn|z.cn)
# Regra: bbs_policy. Corresponde a domínios que terminam com 'bbs.z.cn'.
acl bbs_policy hdr_dom(host) -i bbs.z.cn
# Regra: url_policy. Corresponde a requisições onde a URL contém 'buy_sid='.
acl url_policy url_sub -i buy_sid=
# Direciona para o backend 'server_www' se 'www_policy' for satisfeita.
use_backend server_www if www_policy
# Direciona para o backend 'server_app' se 'url_policy' for satisfeita.
use_backend server_app if url_policy
# Direciona para o backend 'server_bbs' se 'bbs_policy' for satisfeita.
use_backend server_bbs if bbs_policy
# Se nenhuma das regras acima for satisfeita, o tráfego vai para 'server_cache'.
default_backend server_cache
Outro exemplo, demonstrando a combinação de regras:
# Regra: url_static. Corresponde a caminhos de URL que terminam com extensões de arquivos estáticos comuns.
acl url_static path_end -i .gif .png .jpg .css .js
# Regra: host_www. Corresponde a domínios que começam com 'www'.
acl host_www hdr_beg(host) -i www
# Regra: host_static. Corresponde a domínios que começam com 'img.', 'video.', 'download.', 'ftp.'.
acl host_static hdr_beg(host) -i img. video. download. ftp.
# Direciona para o backend 'static' se ambas as regras 'host_static' e 'url_static' forem verdadeiras,
# OU se ambas as regras 'host_www' e 'url_static' forem verdadeiras.
use_backend static if host_static || host_www url_static
# Se 'host_www' for satisfeita (e a regra anterior não), direciona para o backend 'www'.
use_backend www if host_www
# Caso contrário, o tráfego vai para o backend 'server_cache'.
default_backend server_cache
A lógica if A || B C é interpretada como if (A and C) or (B and C).
Configuração de Exemplo
Este exemplo detalha a configuração de um HAProxy para gerenciar três hosts virtuais distintos, distribuindo o tráfego com base no nome do host.
Configuração do HAProxy
$ cat conf/haproxy.cfg
global
maxconn 20000
log 127.0.0.1 local0 info
user nobody
group nobody
chroot /usr/local/haproxy
daemon
pidfile /usr/local/haproxy/logs/haproxy.pid
defaults
mode http
retries 3
timeout connect 10s
timeout client 20s
timeout server 30s
timeout check 5s
frontend www
bind *:80
mode http
log global
option httplog
option forwardfor
option httpclose
option dontlognull
# Regras para direcionar tráfego com base no host
acl acl_www hdr_beg(host) www.zb.com
acl acl_static hdr_beg(host) static.zb.com
acl acl_video hdr_beg(host) video.zb.com
use_backend backend_a if acl_www
use_backend backend_b if acl_static
use_backend backend_c if acl_video
default_backend backend_default
backend backend_default
mode http
option redispatch
option abortonclose
balance roundrobin
cookie SERVERID preserve
option httpchk HEAD /index.html
server web1 10.0.0.6:80 cookie server1 weight 4 check inter 2000 rise 2 fall 3
server web2 10.0.0.7:8000 cookie server2 weight 6 check inter 2000 rise 2 fall 3
timeout connect 5s
timeout server 5s
retries 2
# Backends para diferentes tipos de conteúdo
backend backend_a
mode http
option redispatch
option abortonclose
balance roundrobin
cookie SERVERID preserve
option httpchk HEAD /index.html
server a1 10.0.0.6:81 cookie server1 weight 6 check inter 2000 rise 2 fall 3
server a2 10.0.0.7:81 cookie server2 weight 6 check inter 2000 rise 2 fall 3
backend backend_b
mode http
option redispatch
option abortonclose
balance roundrobin
cookie SERVERID preserve
option httpchk HEAD /index.html
server b1 10.0.0.6:82 cookie server1 weight 6 check inter 2000 rise 2 fall 3
server b2 10.0.0.7:82 cookie server2 weight 6 check inter 2000 rise 2 fall 3
backend backend_c
mode http
option redispatch
option abortonclose
balance roundrobin
cookie SERVERID preserve
option httpchk HEAD /index.html
server c1 10.0.0.6:83 cookie server1 weight 6 check inter 2000 rise 2 fall 3
server c2 10.0.0.7:83 cookie server2 weight 6 check inter 2000 rise 2 fall 3
# Interface de monitoramento
listen stats
bind 0.0.0.0:9188
mode http
log 127.0.0.1 local0 err
stats refresh 30s
stats uri /status
stats realm Admin Area
stats auth admin:admin
stats hide-version
stats admin if TRUE
Configuração dos Servidores Nginx de Backend
Configuração de hosts virtuais em cada servidor Nginx para escutar em portas diferentes.
# Arquivo: /etc/nginx/nginx.conf (simplificado para o contexto)
# ... (configurações globais e de eventos) ...
http {
# ... (configurações http) ...
server {
listen 80;
server_name _;
root /usr/share/nginx/html;
# ... (configurações padrão) ...
}
# Hosts virtuais para os backends do HAProxy
server {
listen 81;
server_name _;
charset utf-8;
location / {
index index.html index.htm;
root /data/a;
}
}
server {
listen 82;
server_name _;
charset utf-8;
location / {
index index.html index.htm;
root /data/b;
}
}
server {
listen 83;
server_name _;
charset utf-8;
location / {
index index.html index.htm;
root /data/c;
}
}
}
Criação de Páginas de Teste
Criação de arquivos index.html distintos para cada diretório em ambos os servidores backend.
Servidor 10.0.0.6:
$ mkdir -p /data/{a,b,c}
$ echo "Conteúdo do Servidor 10.0.0.6 - Backend A" > /data/a/index.html
$ echo "Conteúdo do Servidor 10.0.0.6 - Backend B" > /data/b/index.html
$ echo "Conteúdo do Servidor 10.0.0.6 - Backend C" > /data/c/index.html
# Testar e reiniciar Nginx
$ nginx -t
$ systemctl restart nginx.service
Servidor 10.0.0.7:
$ mkdir -p /data/{a,b,c}
$ echo "Conteúdo do Servidor 10.0.0.7 - Backend A" > /data/a/index.html
$ echo "Conteúdo do Servidor 10.0.0.7 - Backend B" > /data/b/index.html
$ echo "Conteúdo do Servidor 10.0.0.7 - Backend C" > /data/c/index.html
# Testar e reiniciar Nginx
$ nginx -t
$ systemctl restart nginx.service
Acessando os Serviços
Para testar a configuração, utilize a interface de status do HAProxy:
http://10.0.0.5:9188/status
Configuração de DNS Local (Opcional)
Adicione as seguintes entradas ao arquivo hosts do seu cliente para facilitar o acesso via nomes de domínio:
10.0.0.5 www.zb.com
10.0.0.5 static.zb.com
10.0.0.5 video.zb.com
Agora, você pode acessar os serviços usando os nomes de domínio configurados.