Artigo

Como funciona um Load Balancer

15 min de leitura

Seu sistema tá no ar, tudo funcionando. Aí sai uma promoção, um post viraliza, e de repente 50 mil pessoas tentam acessar ao mesmo tempo. O que acontece? Timeout, erro 503, usuário xingando no Twitter.

O problema é simples: você tá jogando todo o tráfego numa máquina só. E a solução tem nome — Load Balancer.

Nesse post eu vou te explicar o que é um Load Balancer, como ele funciona, quais algoritmos ele usa pra distribuir as requisições, onde ele fica na arquitetura, como ele sabe que um servidor morreu, e os erros mais comuns que eu vejo o pessoal cometendo.

O problema: um servidor só não escala

Quando você sobe uma aplicação — pode ser uma API, um site, qualquer coisa — ela roda dentro de um servidor. Esse servidor tem CPU, memória, disco, rede. Tudo finito, tudo limitado.

Com 5 usuários? Tranquilo, ele aguenta. Mas quando chega uma Black Friday com centenas de milhares de requisições, o servidor começa a engasgar. Não tem recurso suficiente pra atender todo mundo.

Visualmente, o cenário é esse:

    [Usuários]
    ||||||||||
    vvvvvvvvvv
  +-----------+
  | Servidor  |  ← CPU 100%, memória estourando
  +-----------+
       |
     TIMEOUT

A primeira reação de muita gente é: "vou botar um servidor mais forte". Mais CPU, mais RAM. Isso se chama escalar verticalmente. E funciona... até um ponto. Porque existe um limite físico — você não pode enfiar infinita RAM numa máquina. E mesmo que pudesse, você tá colocando todos os ovos numa cesta só. Se essa máquina cair, acabou.

A alternativa é escalar horizontalmente: ao invés de um servidor gigante, você usa vários servidores menores fazendo a mesmíssima coisa. 500 requisições por segundo? 100 pra cada um dos 5 servidores.

    [Usuários]
    ||||||||||
    vvvvvvvvvv
  +-----------+
  |     ?     |  ← quem decide pra onde vai?
  +-----------+
   /    |    \
  v     v     v
+---+ +---+ +---+
| S1| | S2| | S3|
+---+ +---+ +---+

Assim você divide a carga e diminui o atrito de memória, CPU e tudo mais. Só que aí vem a pergunta: quem é esse ? no meio? Quem decide qual requisição vai pra qual servidor?

O que é um Load Balancer

Load Balancer, traduzindo ao pé da letra, é um balanceador de carga. É exatamente isso que ele faz: fica na frente dos seus servidores e distribui as requisições entre eles.

O cliente faz a requisição, ela bate no Load Balancer, e ele decide pra qual servidor encaminhar. O cliente nunca precisa saber quantas instâncias existem por trás — pra ele, existe um endereço só.

        [Cliente]
            |
            v
     seusite.com.br
            |
            v
    +---------------+
    | Load Balancer |
    +---------------+
     /      |      \
    v       v       v
 +----+  +----+  +----+
 | S1 |  | S2 |  | S3 |
 +----+  +----+  +----+

Quando o cliente acessa seusite.com.br, ele não tá requisitando a aplicação diretamente. Ele tá requisitando o Load Balancer. É o Load Balancer que redireciona.

E se um servidor morrer? O Load Balancer para de mandar tráfego pra ele. As próximas requisições vão pros outros. O usuário nem percebe que teve alguma falha.

Você ganha duas coisas de uma vez:

  • Performance — a carga fica dividida, nenhum servidor sobrecarrega
  • Disponibilidade — se um cair, os outros seguram o tráfego

E uma dúvida que sempre aparece: "mas o Load Balancer não teria o mesmo problema de carga? Se tá todo mundo requisitando ele no meio?"

Até pode, mas o Load Balancer é um serviço muito mais leve do que a sua aplicação. Ele não processa regra de negócio, não consulta banco, não faz nada pesado. Ele só redireciona. Pra você conseguir sobrecarregar um Load Balancer a ponto dele cair, teria que ser uma quantidade de requisições absurdamente maior do que qualquer aplicação de porte médio vai receber.

Algoritmos de balanceamento

Beleza, o Load Balancer distribui as requisições. Mas como ele decide pra onde cada uma vai? Existem vários algoritmos. Vou passar pelos principais.

Round Robin

O mais simples de todos. Primeira requisição vai pro servidor 1, segunda pro 2, terceira pro 3, e quando chega no último, volta pro primeiro. Igual uma roleta.

Requisição 1  →  Servidor A
Requisição 2  →  Servidor B
Requisição 3  →  Servidor C
Requisição 4  →  Servidor A  ← volta pro início
Requisição 5  →  Servidor B
Requisição 6  →  Servidor C
...

Cada servidor recebe igualmente a quantidade de requisições. É simples, fácil de implementar, e funciona perfeitamente quando os servidores são iguais em capacidade (mesma CPU, mesma memória).

Quando usar: servidores idênticos, requisições com tempo de processamento parecido.

Quando não usar: servidores com capacidades diferentes ou requisições que variam muito em tempo de processamento.

Weighted Round Robin

Mesma lógica do Round Robin, mas com pesos. Você informa pro Load Balancer: "esse servidor aqui aguenta o dobro de requisições, então manda mais pra ele".

Servidor A (peso 1):  recebe 1 requisição por ciclo
Servidor B (peso 3):  recebe 3 requisições por ciclo
Servidor C (peso 1):  recebe 1 requisição por ciclo

Resultado: A, B, B, B, C, A, B, B, B, C...

É como ter dois entregadores, um de moto e outro de carro. O de carro leva mais carga porque tem mais espaço. Você não vai dar a mesma quantidade de entregas pros dois.

Quando usar: servidores com capacidades diferentes (o que é super comum quando você vai escalando aos poucos e não troca tudo de uma vez).

Least Connections

Esse é mais esperto. Ao invés de distribuir sequencialmente, ele olha: qual servidor tem menos conexões ativas nesse momento? E manda pra ele.

Estado atual:
  Servidor A: 100 conexões ativas
  Servidor B:  90 conexões ativas
  Servidor C:  70 conexões ativas

Nova requisição → Servidor C (menos conexões)

Estado atualizado:
  Servidor A: 100
  Servidor B:  90
  Servidor C:  71  ← recebeu a nova

Próxima requisição → Servidor C de novo (ainda é o menor)
...até equilibrar com o B, e aí começa a mandar pro B também.

Isso é muito útil quando as requisições têm tempos de processamento diferentes. Uma pode retornar em 50ms, outra pode demorar 5 segundos. O Round Robin não sabe disso — ele só distribui na ordem. O Least Connections olha a situação real.

Quando usar: requisições com tempos de processamento variados, sistemas onde algumas rotas são mais pesadas que outras.

IP Hash

Esse pega o IP do usuário, faz um cálculo em cima dele, e gera um hash. Com esse hash, ele decide pra qual servidor mandar. E como o hash do mesmo IP sempre dá o mesmo resultado, o usuário sempre cai no mesmo servidor.

IP 192.168.1.10  →  hash()  →  Servidor A  (sempre)
IP 192.168.1.25  →  hash()  →  Servidor C  (sempre)
IP 10.0.0.50     →  hash()  →  Servidor B  (sempre)

Isso é importante quando a aplicação depende de sessão — tipo um carrinho de compras salvo na memória do servidor, ou autenticação por sessão. Se o usuário cair em servidor diferente, não vai ter a informação que ele tinha. O carrinho some, a sessão expira, vira bagunça.

Quando usar: aplicações que guardam estado local no servidor (sessão, cache em memória).

Porém: IP Hash é mais um paliativo do que uma solução. O ideal é externalizar o estado — jogar a sessão no Redis, no banco, em qualquer lugar que todos os servidores consigam acessar. Aí você não depende mais de afinidade e qualquer algoritmo funciona.

Comparativo rápido

Round Robin

  • Como decide: na ordem, um por vez
  • Melhor pra: servidores iguais
  • Limitação: ignora capacidade e carga real

Weighted Round Robin

  • Como decide: na ordem, com peso
  • Melhor pra: servidores com capacidades diferentes
  • Limitação: ignora carga real

Least Connections

  • Como decide: manda pro servidor com menos conexões ativas
  • Melhor pra: carga variável, requisições com tempos diferentes
  • Limitação: mais overhead de monitoramento

IP Hash

  • Como decide: hash do IP do cliente
  • Melhor pra: afinidade de sessão
  • Limitação: distribuição pode ficar desigual

Na prática, a maioria dos Load Balancers usa os mesmos algoritmos. O que muda é como você configura pro seu cenário.

Onde ele fica na arquitetura

O Load Balancer é a porta de entrada do seu sistema. Mas ele pode atuar em camadas diferentes, e isso muda o que ele consegue fazer.

Camada 7 — Load Balancer de aplicação

Opera na camada de aplicação (HTTP/HTTPS). Isso significa que ele entende o conteúdo da requisição — URL, headers, cookies, método HTTP.

Com isso, ele consegue tomar decisões inteligentes:

    [Cliente]
        |
        v
+------------------+
| Load Balancer L7 |
+------------------+
   |            |
   | /api/*     | /images/*
   v            v
+--------+  +----------+
| API    |  | Servidor |
| Cluster|  | Estático |
+--------+  +----------+

Requisição pra /api? Manda pro cluster de API. Requisição pra /images? Manda pro servidor de arquivos estáticos. Isso funciona como um proxy reverso — o cliente faz uma requisição só, e o Load Balancer roteia pra onde tem que ir.

Você também consegue fazer coisas como:

  • Rotear por header (ex: versão da API)
  • Rotear por cookie (ex: A/B testing)
  • Fazer SSL termination (descriptografar HTTPS no Load Balancer e passar HTTP pros servidores internos)
  • Injetar headers customizados

É o tipo mais comum e mais flexível.

Camada 4 — Load Balancer de rede

Opera na camada de transporte (TCP/UDP). Ele não entende HTTP. Só olha IP de origem, IP de destino e porta. E redireciona.

    [Cliente]
        |
        v
+------------------+
| Load Balancer L4 |  ← só olha IP + porta
+------------------+
   /      |      \
  v       v       v
+----+  +----+  +----+
| S1 |  | S2 |  | S3 |
+----+  +----+  +----+

É mais rápido porque não precisa parsear o conteúdo da requisição. Mas não tem inteligência de roteamento — não sabe diferenciar /api de /images.

Quando usar: quando você precisa de alta performance e throughput, tipo jogos online, streaming, ou proxies de banco de dados.

Combinando os dois

Empresas grandes costumam combinar:

         [Cliente]
             |
             v
    +------------------+
    | Load Balancer L4 |  ← distribui entre LBs de L7
    +------------------+
       /           \
      v             v
+----------+  +----------+
| LB L7 #1 |  | LB L7 #2 |
+----------+  +----------+
  /    \        /    \
 v      v      v      v
+--+  +--+  +--+  +--+
|S1|  |S2|  |S3|  |S4|
+--+  +--+  +--+  +--+

Um Load Balancer L4 na frente distribui entre vários Load Balancers L7. Cada L7 distribui entre os servidores de aplicação. Assim você tem performance na entrada e inteligência no roteamento.

Health Check: como ele sabe que o servidor tá vivo

O Load Balancer não é burro. Ele não manda requisição pra servidor morto. Mas pra saber se tá morto ou não, ele usa um processo chamado Health Check.

Funciona assim: cada servidor expõe uma rota, geralmente /health. De tempos em tempos, o Load Balancer faz uma requisição GET pra essa rota. Se responde 200 com um "healthy", tá vivo. Se não responde — ou responde com erro — tá morto.

Load Balancer
    |
    |---GET /health--→ Servidor A  →  200 OK ✓
    |---GET /health--→ Servidor B  →  200 OK ✓
    |---GET /health--→ Servidor C  →  TIMEOUT ✗  ← morto
    |
    | (a cada 10s, repete)

Quando um servidor falha no Health Check, o Load Balancer tira ele da rotação. Para de mandar tráfego pra ele. As requisições vão pros que estão vivos.

Antes:    LB → [A, B, C]
Depois:   LB → [A, B]     (C removido)

E quando o servidor volta a responder? O Load Balancer coloca ele de volta. Tudo automático.

Na prática, você configura:

  • Intervalo: de quanto em quanto tempo faz o check (ex: a cada 10 segundos)
  • Threshold de falha: quantas falhas consecutivas pra considerar morto (ex: 3 falhas seguidas)
  • Threshold de recuperação: quantos sucessos pra considerar vivo de novo (ex: 2 sucessos seguidos)

Esse ajuste fino faz diferença. Se você define 1 falha como threshold, qualquer instabilidade momentânea tira o servidor da rotação. Se define 10, demora demais pra reagir a uma falha real.

Sem Health Check, você ia mandar requisições pra servidores mortos que iam retornar 500, 404... e o cliente ia sofrer por isso. Com Health Check, você consegue falhar sem ninguém perceber.

E não para aí. Você precisa de observabilidade em cima disso. Quando o Load Balancer tira um servidor da rotação, você precisa ser avisado — alerta no Slack, no email, onde for. Porque o Load Balancer desvia o tráfego, mas não corrige o problema. Quem corrige é você.

Ferramentas do mercado

No mundo real você tem duas opções: self-hosted ou gerenciado pela cloud.

Self-hosted

Nginx Provavelmente o mais famoso. Não é só um Load Balancer — ele funciona como servidor web e proxy reverso também. Muita gente usa como Load Balancer porque ele faz isso muito bem.

Um exemplo básico de configuração:

1upstream backend { 2 server 10.0.0.1:8080; 3 server 10.0.0.2:8080; 4 server 10.0.0.3:8080; 5} 6 7server { 8 listen 80; 9 10 location / { 11 proxy_pass http://backend; 12 } 13}

Isso já distribui as requisições entre os 3 servidores usando Round Robin (o padrão do Nginx).

HAProxy Totalmente focado em ser Load Balancer. A maioria das empresas grandes usam ou já usaram. Estabilidade absurda, performance de alta carga.

1frontend http_front 2 bind *:80 3 default_backend servers 4 5backend servers 6 balance roundrobin 7 option httpchk GET /health 8 server s1 10.0.0.1:8080 check 9 server s2 10.0.0.2:8080 check 10 server s3 10.0.0.3:8080 check

Repara que já tem o option httpchk configurado — Health Check nativo. E o balance roundrobin define o algoritmo. Pra trocar pra Least Connections, é só mudar pra balance leastconn.

Cloud (gerenciado)

  • AWS: ALB (Application Load Balancer, L7) e NLB (Network Load Balancer, L4)
  • GCP: Cloud Load Balancing (L4 e L7)
  • Azure: Azure Load Balancer (L4) e Application Gateway (L7)

A vantagem do gerenciado: você não se preocupa com a infraestrutura do Load Balancer em si. Ele já tem Health Check, failover, auto-scaling, SSL termination... tudo pronto.

A desvantagem: menos controle fino e vendor lock-in.

Se você tá numa startup ou num projeto que tá começando, cloud gerenciada resolve e você não precisa pensar nisso. Se você precisa de controle total ou tá num cenário on-premise, Nginx ou HAProxy.

Encontrar solução de Load Balancer é fácil. Configurar direito é que é o desafio.

Erros comuns

1. Não configurar Health Check

O Load Balancer precisa saber que o servidor morreu. Se ele não souber, o cliente vai saber.

Você coloca o Load Balancer, bota os servidores atrás dele, e esquece de configurar checagem. Aí um servidor morre e o Load Balancer continua mandando tráfego pra ele. O usuário toma 500 na cara.

Configura o Health Check. Sempre. E adiciona observabilidade — logs, alertas, ferramentas de monitoramento. Quando o Load Balancer tirar um servidor da rotação, você precisa saber.

2. Não pensar na sessão

Algumas aplicações guardam sessão na memória do servidor. Não é o ideal, mas acontece. Aí a pessoa vai lá, escala a aplicação, coloca mais servidores, e esquece que tem sessão gerenciada local.

O que acontece: o usuário faz a primeira requisição, tudo certo. Faz a segunda, cai em outro servidor, perde o dado da primeira. Carrinho sumiu, login expirou, estado perdeu.

Req 1 → Servidor A (cria sessão)
Req 2 → Servidor B (sessão não existe aqui) ← problema

A solução certa é externalizar o estado: joga a sessão no Redis, no banco, em qualquer lugar compartilhado. Aí qualquer servidor consegue acessar e não importa onde a requisição cai.

Req 1 → Servidor A → grava sessão no Redis
Req 2 → Servidor B → lê sessão do Redis ← funciona

Se não der pra externalizar agora, use IP Hash como paliativo. Mas saiba que é temporário.

3. Achar que Load Balancer resolve tudo

Esse é o mais perigoso. O sistema tá lento, a pessoa coloca mais servidores e um Load Balancer na frente achando que vai resolver.

Se você tem query mal feita, banco mal otimizado, processo lento — vai ficar lento de qualquer jeito. Load Balancer distribui carga. Não faz código rodar mais rápido.

Se sua query demora 10 segundos, colocar 10 servidores atrás de um Load Balancer só vai dar 10 respostas lentas ao mesmo tempo.

Antes de escalar horizontalmente, garante que o sistema tá otimizado. Depois escala.

Resumo visual

                    [Clientes]
                        |
                        v
                 +-------------+
                 |     DNS     |
                 +-------------+
                        |
                        v
              +-----------------+
              | Load Balancer   |
              | (L7 ou L4)     |
              | - Algoritmo     |
              | - Health Check  |
              | - SSL Term.     |
              +-----------------+
               /       |       \
              v        v        v
          +------+ +------+ +------+
          |  S1  | |  S2  | |  S3  |  ← aplicação
          |/health|/health|/health|
          +------+ +------+ +------+
              \       |       /
               v      v      v
            +------------------+
            |     Database     |
            +------------------+

Conclusão

Load Balancer é uma peça fundamental de qualquer sistema que precisa escalar. Ele distribui requisições, melhora performance, aumenta disponibilidade e permite que você cresça sem depender de uma máquina só.

Mas é só uma peça. Arquitetura é sobre entender como as peças se encaixam — e eu falo sobre isso toda semana.

Se você quer ver isso funcionando na prática com diagrama e explicação visual, gravei um vídeo montando a arquitetura completa. E se quer ir mais fundo nas decisões práticas — qual algoritmo escolher, quando IP Hash é paliativo, por que Health Check é obrigatório — escrevi uma newsletter detalhando tudo isso. No LinkedIn, também postei um resumo direto ao ponto pra você salvar e consultar depois.


Racoelho

Conteúdo sobre desenvolvimento, tecnologia e desafios de programação para impulsionar sua carreira em tech.

Conecte-se

© 2024- 2026 Racoelho. Todos os direitos reservados.

v3.0.14 • Build: 2025-12-04