Pular para conteúdo

a. Visão geral

Objetivo principal

O objetivo principal deste hands-on é adicionar um balanceador de carga na frente do gateway usando o Nginx, permitindo o escalonamento horizontal do serviço de gateway em várias réplicas dentro do Docker Compose.

Os hands-on anteriores construíram uma plataforma de microsserviços com uma única instância de gateway atendendo todo o tráfego externo. Sob carga contínua, esse gateway se torna um gargalo — um processo, um pool de threads, nenhuma redundância. Um balanceador de carga resolve isso distribuindo as requisições recebidas entre várias instâncias idênticas do mesmo serviço.

Proxy

Um proxy é um intermediário que fica entre clientes e servidores, encaminhando requisições em nome de um dos lados.

Um forward proxy fica na frente dos clientes. Ele encaminha as requisições de saída para a internet e devolve a resposta ao cliente. O servidor de destino vê o endereço do proxy, e não o do cliente original.

Usos comuns: firewalls corporativos, filtragem de conteúdo, anonimização (VPN, Tor).

flowchart LR
    client1[Cliente 1] --> fp[Forward Proxy]
    client2[Cliente 2] --> fp
    fp -->|IP mascarado| server[Internet / Servidor]

Um reverse proxy (proxy reverso) fica na frente dos servidores. Ele recebe as requisições vindas da internet e as encaminha para os servidores de backend internos. O cliente enxerga apenas o proxy — nunca os endereços do backend.

Usos comuns: balanceamento de carga, terminação SSL, cache, rate limiting.

flowchart LR
    internet[Internet] --> rp[Reverse Proxy]
    rp --> s1[Backend 1]
    rp --> s2[Backend 2]
    rp --> s3[Backend 3]

Neste hands-on, o Nginx atua como proxy reverso — o único componente exposto na porta 80, distribuindo o tráfego para réplicas do gateway que permanecem invisíveis para os clientes externos.

Tipos de balanceador de carga

Os balanceadores de carga são classificados pela camada OSI em que inspecionam o tráfego:

Roteia o tráfego com base apenas no endereço IP e na porta TCP/UDP. O balanceador nunca inspeciona o payload HTTP — ele simplesmente encaminha fluxos de bytes.

  • Overhead de processamento mínimo — extremamente rápido
  • Independente de protocolo: funciona para qualquer serviço TCP/UDP
  • Não consegue rotear com base no caminho da URL, em cabeçalhos HTTP ou em cookies

Exemplos: AWS Network Load Balancer (NLB), HAProxy em modo TCP.

flowchart LR
    client -->|"TCP :443"| lb["Balanceador L4\n(IP + Porta)"]
    lb -->|"10.0.0.1:8080"| s1[Servidor 1]
    lb -->|"10.0.0.2:8080"| s2[Servidor 2]
    lb -->|"10.0.0.3:8080"| s3[Servidor 3]

Roteia o tráfego com base no conteúdo HTTP: caminho da URL, cabeçalhos, cookies ou corpo da requisição. Permite decisões de roteamento muito mais inteligentes.

  • Pode inspecionar, modificar e reescrever requisições e respostas
  • Permite sessões fixas (sticky sessions), roteamento A/B e roteamento por caminho para serviços diferentes
  • Pequeno overhead em relação ao L4 — desprezível na maioria dos workloads

Exemplos: Nginx, Traefik, AWS Application Load Balancer (ALB).

flowchart LR
    client --> lb["Balanceador L7\n(entende HTTP)"]
    lb -->|"/api/auth/*"| auth[Serviço Auth]
    lb -->|"/api/accounts/*"| account[Serviço Account]
    lb -->|"Cookie: region=eu"| eu[Backend EU]

Algoritmos de balanceamento de carga

Algoritmo Comportamento Indicado para
Round Robin Requisições distribuídas sequencialmente, uma por servidor, em ordem Workloads uniformes, réplicas de mesma capacidade
Least Connections A próxima requisição vai para o servidor com menos conexões ativas Conexões longas, requisições de duração variável
IP Hash O IP do cliente determina qual servidor atende todas as suas requisições Afinidade de sessão (aplicações com estado)
Weighted Round Robin Os servidores recebem uma fatia proporcional a um peso atribuído Servidores de capacidades diferentes
Random Servidor escolhido aleatoriamente a cada requisição Clusters muito grandes, simplicidade em escala

Arquitetura

Adicionar o Nginx como balanceador de carga muda o ponto de entrada da plataforma. O gateway deixa de ser exposto diretamente — apenas o Nginx é acessível de fora da rede Docker:

flowchart LR
    subgraph api [Camada Confiável]
        gateway:::orange --> auth
        gateway --> account
        account --> db@{ shape: cyl, label: "Banco de dados" }
    end
    internet e1@==>|":8080"| gateway
    e1@{ animate: true }
    classDef orange fill:#FCBE3E
flowchart LR
    subgraph lb [Camada de Balanceamento de Carga]
        nginx["Nginx\n:80"]:::highlighted
    end
    subgraph api [Camada Confiável]
        gw1["gateway\n(réplica 1)"]
        gw2["gateway\n(réplica 2)"]
        gw3["gateway\n(réplica 3)"]
        auth[auth]
        account[account]
        db@{ shape: cyl, label: "Banco de dados" }
        gw1 & gw2 & gw3 --> auth & account
        account --> db
    end
    internet e0@==>|":80"| nginx
    nginx e1@==> gw1
    nginx e2@==> gw2
    nginx e3@==> gw3
    e0@{ animate: true }
    e1@{ animate: true }
    e2@{ animate: true }
    e3@{ animate: true }
    classDef highlighted fill:#fcc

Os passos para implementar isso são:

  • Nginx


    Crie o arquivo de configuração do Nginx definindo o pool upstream e as regras de proxy reverso.

    Nginx

  • Docker Compose


    Adicione o serviço nginx ao compose.yaml, remova a porta exposta do gateway e configure as réplicas.

    Docker Compose

  • Execução


    Suba a stack completa e verifique se o Nginx distribui as requisições entre as réplicas do gateway.

    Execução