Home Comunidade Eventos YouTube Networks Desafios // produtos Academy News CTI | CVE Contato

02 - Hardware vs Software (HAProxy, Nginx)

#balanceamento#haproxy#load-balancer#nginx#open-source
video explicativo
Video explicativoEspaco reservado para o video desta anotação — adicione video: https://youtu.be/... no frontmatter da nota.

Hardware vs Software (HAProxy, Nginx)

Balanceamento de carga pode ser entregue por appliances dedicados de hardware ou por software rodando em servidores comuns e máquinas virtuais, e essa divisão define custo, flexibilidade e modelo de operação. O appliance de hardware é uma caixa pronta, com ASICs de criptografia, suporte contratual do fabricante e desempenho previsível, mas com preço alto, ciclo de aquisição lento e capacidade fixada no dia da compra. O software, representado por HAProxy e Nginx, roda em qualquer infraestrutura, escala com provisionamento e evolui em ciclos de semanas, sendo o modelo dominante em nuvem e o padrão de facto em arquiteturas modernas. A discussão não é religiosa, é de requisito: datacenters próprios com requisitos de certificação e desempenho garantido ainda justificam hardware, enquanto praticamente todo ambiente de nuvem resolve o problema com software, gerenciado ou não. O domínio do tema, para quem projeta produção, está em entender o que cada ferramenta de software sabe fazer bem, porque é com elas que a maioria dos ambientes realmente opera.

Conceito e problema que resolvem

O appliance de hardware nasceu num mundo em que servidores eram caros, a rede era o gargalo e a compra de capacidade era projeto de meses. Fornecedores como F5, Citrix e A10 entregam caixas com aceleração dedicada de TLS, compressão em silício e um ecossistema de configuração proprietário, com SLA de suporte e substituição física. O ganho é previsibilidade de desempenho e responsabilidade contratual; o custo é a licença, a rigidez e a obsolescência programada, porque redimensionar significa comprar nova caixa.

O software resolve o mesmo problema com produtos que competem em desempenho com hardware dedicado: HAProxy sustenta centenas de milhares de conexões simultâneas em um nó dimensionado, e Nginx, nascido para resolver o problema C10K, serve de proxy reverso e balanceador com consumo de memória mínimo por conexão. O ganho é elasticidade, custo marginal próximo de zero e automação total, já que configuração é arquivo texto versionado em repositório. O custo é assumir a operação: patches, dimensionamento, alta disponibilidade do próprio balanceador e expertise da equipe.

O problema que ambos resolvem é idêntico: distribuir carga entre destinos, remover destinos doentes do pool e servir de ponto único de entrada com terminação de protocolo. O que muda é o contrato de aquisição e a velocidade de mudança, e é nesse eixo que a decisão arquitetural se apoia.

HAProxy em detalhe

O HAProxy é um balanceador puro, focado em disponibilidade e desempenho, e é a referência quando a exigência é distribuição de alta precisão. Ele opera em dois modos principais: modo TCP, que encaminha fluxo bruto sem interpretar aplicação, e modo HTTP, que termina e inspeciona requisições, permitindo regras por path, header e cookie, equivalente funcional à distinção L4 e L7.

Os health checks do HAProxy são extensos: TCP, HTTP com verificação de código, envio de corpo e verificação de string, e checks específicos para PostgreSQL, MySQL, Redis, SMTP e LDAP, algo que poucos concorrentes oferecem. A retirada de destino respeita períodos de observação e drenagem, e os algoritmos cobrem round robin, least connections, source hash, URI hash e first, além de pesos dinâmicos.

A ferramenta de estatísticas é um diferencial operacional: a página de stats nativa e o socket de administração expõem em tempo real a taxa de requisição, a fila por backend, o estado de cada servidor e o tempo de resposta médio, e a mesma interface permite drenar um servidor em produção com um comando, sem reload. O runtime API via socket também permite adicionar e remover destinos sem reiniciar, o que integra bem com descoberta de serviço.

# Exemplo de configuração do HAProxy (haproxy.cfg)
global
    maxconn 50000                     # limite global de conexões simultâneas
    log stdout format raw local0      # log estruturado para stdout, bom para contêiner

defaults
    mode http                         # modo HTTP habilita inspeção de camada 7
    log global
    option httplog
    timeout connect 5s                # tempo para abrir conexão com o backend
    timeout client  30s
    timeout server  30s
    retries 3

frontend entrada_api
    bind *:443 ssl crt /etc/haproxy/certs/api.pem alpn h2,http/1.1
    # Terminação TLS centralizada com negociação HTTP/2

    # Roteamento por path: pedidos e relatorios em clusters distintos
    acl path_pedidos     path_beg /v1/pedidos
    acl path_relatorios  path_beg /v1/relatorios
    use_backend bk_pedidos     if path_pedidos
    use_backend bk_relatorios  if path_relatorios
    default_backend bk_pedidos

backend bk_pedidos
    balance leastconn                 # bom para tempos de resposta variáveis
    option httpchk GET /healthz       # health check HTTP real
    http-check expect status 200
    server pedidos-1 10.0.1.11:8080 check maxconn 500 weight 100
    server pedidos-2 10.0.1.12:8080 check maxconn 500 weight 100
    server pedidos-3 10.0.1.13:8080 check maxconn 500 weight 50 backup

listen estatisticas
    bind *:8404
    stats enable
    stats uri /stats                  # painel de estatísticas nativo

Nginx em detalhe

O Nginx é mais amplo que um balanceador: é servidor web, proxy reverso, cache HTTP e balanceador, e essa amplitude é a razão de sua ubiquidade. Como proxy reverso, ele posiciona a aplicação atrás de um ponto que adiciona compressão, terminação TLS, cache de respostas estáticas e limitação de taxa, e o balanceamento é um recurso dentro desse contexto maior.

O bloco upstream define o pool de destinos e o algoritmo: round robin é o default, least_conn escolhe por menor número de conexões ativas, ip_hash fornece afinidade por IP de origem, e os pesos atribuem capacidade relativa. Os health checks ativos com sondagem de aplicação são recurso da edição comercial, enquanto a edição open source usa verificação passiva, marcando servidor como indisponível a partir de erros e timeouts observados no tráfego real, com max_fails e fail_timeout.

O ponto forte do Nginx em produção é atuar como camada única de edge: ele responde estático com eficiência extrema, cacheia respostas de APIs em proxy_cache com regras por header e TTL, aplica rate limiting por chave e concentra políticas de header de segurança. Em ambientes Kubernetes, essa mesma lógica aparece no ingress-nginx, o que multiplica o número de equipes que operam o produto sem perceber.

Aspecto Hardware (appliance) HAProxy Nginx
Modelo de aquisição CAPEX, licença e suporte Open source ou enterprise Open source ou comercial
Desempenho por nó Alto, aceleração dedicada Altíssimo, otimizado para proxy Alto, eficiente em estático
Modos de operação TCP e HTTP completos TCP e HTTP HTTP e TCP (stream)
Health checks ativos Sim, variados Sim, com checks por banco Passivo no open source
Cache de conteúdo Sim Não foco Sim, proxy_cache
Elasticidade de escala Compra de nova caixa Provisionar mais nós Provisionar mais nós
Curva de mudança Semanas a meses Minutos, reload sem queda Minutos, reload sem queda
Caso ideal Datacenter com SLA rígido Balanceamento puro crítico Edge, proxy e estático

Algoritmos de distribuição

Os algoritmos são o vocabulário comum das duas ferramentas, e a escolha correta depende do padrão de latência da aplicação.

  • Round robin: distribui ciclicamente sem olhar carga; correto quando os destinos são homogêneos e as requisições têm custo parecido.
  • Weighted round robin: adiciona pesos, útil em migração gradual, mistura de hardware e canary com percentual controlado.
  • Least connections: envia a requisição ao destino com menos conexões ativas; é a escolha padrão quando o tempo de resposta varia entre requisições, porque evita empilhar trabalho no nó mais lento.
  • Source IP hash: derivado do IP do cliente, dá afinidade sem estado; serve como mitigação de sessão e ajuda em cache por origem.
  • URI hash: deriva do URI da requisição, direcionando o mesmo recurso sempre ao mesmo destino, o que multiplica a eficiência de cache local por nó.
  • First: sempre usa o destino menos carregado e só recorre ao seguinte ao atingir maxconn, maximizando economia em ambientes com escala vertical.

O erro frequente é tratar round robin como default universal: com requisições de custo desigual, ele gera filas desiguais perceptíveis no p99, e a troca por least connections costuma resolver sem mudar infraestrutura.

Alta disponibilidade e modelo de custo

O balanceador é o componente que não pode cair, e a solução para o ponto único de falha é par de nós com IP flutuante, tradicionalmente via VRRP com Keepalived no ambiente on-premises, e instâncias em zonas distintas com automação de failover na nuvem. O HAProxy se integra nativamente ao Keepalived, e o padrão é ativo-passivo com verificação de saúde entre pares; Nginx segue a mesma linha.

O TCO do hardware inclui aquisição, espaço, energia, renovação e contrato de suporte, com a peculiaridade de que capacidade ociosa é capital parado: dimensionar para o pico do ano seguinte significa pagar hoje. O modelo de software paga o que usa, e o custo cresce quase linear com o tráfego, o que é economicamente superior em carga variável e inferior quando a carga é constante e muito alta e o appliance amortizado já existe. A migração típica de custo acontece quando a caixa precisa ser renovada: substituir hardware por par de HAProxy em nuvem costuma reduzir o gasto mensal em ordem de grandeza, com ganho de automação.

Exemplo de Nginx como proxy reverso e balanceador

# Nginx concentrando proxy reverso, cache e balanceamento
upstream aplicacao {
    least_conn;                              # menor número de conexões ativas
    server app-1.internal:8080 weight=3;     # nó maior recebe peso maior
    server app-2.internal:8080 weight=1;
    keepalive 32;                            # pool de conexões reutilizadas
}

# Zona compartilhada de estado passivo entre workers
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=respostas:50m
                 max_size=2g inactive=10m use_temp_path=off;

server {
    listen 443 ssl http2;
    server_name app.exemplo.com.br;

    # Limitação de taxa por IP: 20 requisições por segundo com rajada de 40
    limit_req_zone $binary_remote_addr zone=api:10m rate=20r/s;

    location /api/ {
        limit_req zone=api burst=40 nodelay;
        proxy_pass http://aplicacao;
        proxy_http_version 1.1;
        proxy_set_header Connection "";

        # Cache de respostas GET por 5 minutos no edge
        proxy_cache respostas;
        proxy_cache_valid 200 5m;
        proxy_cache_key "$scheme$request_method$host$request_uri";
        add_header X-Cache-Status $upstream_cache_status;
    }

    location /healthz {
        return 200 "ok\n";                   # endpoint barato para sondas externas
    }
}

# Bloco TCP puro (stream): balanceia Redis sem interpretar protocolo
stream {
    upstream redis_pool {
        server redis-1.internal:6379;
        server redis-2.internal:6379;
    }
    server {
        listen 6379;
        proxy_pass redis_pool;
        proxy_connect_timeout 3s;
    }
}

Esse exemplo concentra os papéis que fazem o Nginx ser onipresente: terminação com HTTP/2, limitação de taxa, cache no edge, distribuição ponderada e balanceamento TCP puro de um serviço de estado. O mesmo arquivo serve de base para o ingress-nginx em Kubernetes, o que torna o domínio da sintaxe transferível entre ambientes. A leitura arquitetural é que o Nginx é ferramenta de camada de borda, e o HAProxy é ferramenta de distribuição especializada; os dois no mesmo desenho são comuns e não redundantes, cada um cuidando do seu papel.

Erros comuns e boas práticas

  • Balanceador como ponto único: um só nó de HAProxy ou Nginx é o elo mais frágil do desenho; sempre par com failover, em zonas distintas.
  • Reload sem verificar sintaxe: mudança de configuração com erro derruba o serviço no reload; valide sempre com o modo de teste do binário antes de aplicar.
  • Sem logs de decisão: sem registro de destino escolhido e tempo de resposta, investigar desequilíbrio é chutar; habilite logs completos por requisição.
  • Health check passivo onde deveria ser ativo: esperar erro real para retirar destino atrasa a reação; em HAProxy, configure sondas ativas por aplicação.
  • Misturar papéis sem plano de capacidade: Nginx que serve estático, cacheia e balanceia precisa de dimensionamento dedicado, senão o cache compete com o proxy por CPU e disco.
  • Ignorar limites do sistema operacional: file descriptors, portas efêmeras e buffers de rede limitam o software antes do hardware; ajuste sysctl no dimensionamento.

A boa prática consolidada é versionar a configuração em repositório, validar em pipeline, aplicar com reload sem queda e monitorar o próprio balanceador como primeiro sinal de incidente. Em nuvem gerenciada, o mesmo pensamento se aplica ao avaliar o serviço gerenciado contra o par auto-hospedado: o gerenciado elimina operação e cobra por uso, e o auto-hospedado dá controle total e exige time dedicado, exatamente o mesmo eixo de trade-off do hardware contra o software.