System Design/02 - Componentes/Application Layer2 min
Service Discovery
- Que problema isso resolve?
- Quando usar / quando NÃO usar?
- Qual o principal trade-off?
- Como isso falha em produção?
Conceito
Em ambiente dinâmico, instâncias sobem, morrem e mudam de IP o tempo todo. Service discovery responde "onde está o serviço X agora?" sem configuração estática.
Peças: um registro (lista de instâncias saudáveis), mecanismo de registro/baixa, e health check que remove quem parou de responder.
Os dois modelos
| Client-side | Server-side | |
|---|---|---|
| Quem consulta o registro | O cliente | Um balanceador na frente |
| Balanceamento | No cliente | No balanceador |
| Saltos de rede | Um | Dois |
| Complexidade no cliente | Alta (biblioteca por linguagem) | Baixa |
| Exemplos | Eureka + Ribbon | ELB, Kubernetes Service |
Service mesh — a terceira via
O Sidecar intercepta o tráfego e resolve discovery, balanceamento, retry, mTLS e telemetria fora do código da aplicação. É client-side sem biblioteca por linguagem — ao custo de mais um processo por pod e de um plano de controle para operar.
| Ferramenta | Natureza |
|---|---|
| Consul, etcd, ZooKeeper | Registro distribuído (CP) |
| Kubernetes DNS / Service | Discovery embutido no orquestrador |
| Eureka | Registro AP, tolera partição |
| Istio, Linkerd | Service mesh |
Trade-offs
O registro é, ele mesmo, um sistema distribuído — sujeito ao CAP Theorem. Um registro CP recusa responder durante partição, o que pode paralisar todo o discovery. Um registro AP sempre responde, e pode devolver instâncias já mortas.
Eureka escolheu AP deliberadamente: é melhor tentar uma instância morta (e falhar rápido, com retry) do que não descobrir nenhuma. Mesma lógica de Availability vs Consistency.
Health check tem o trade-off de Fail-Over: agressivo demais remove instâncias saudáveis sob carga; frouxo demais mantém instâncias mortas recebendo tráfego.
DNS como discovery é simples e sofre de cache: TTL curto ajuda, mas bibliotecas que cacheiam resolução indefinidamente (o caso clássico da JVM) continuam falando com IPs mortos.
Exemplo prático
Num cluster Kubernetes, http://pedidos resolve pelo DNS interno para o ClusterIP do Service. O kube-proxy encaminha para um dos pods saudáveis listados no Endpoints, que o controlador mantém atualizado conforme os pods sobem e morrem.
O desenvolvedor escreve uma URL fixa; a infraestrutura resolve discovery, balanceamento e remoção de pod morto. É server-side discovery com o registro embutido no orquestrador — o modelo que virou padrão justamente por tirar o problema do código.
Relacionado
Parte de Application Layer · roadmap.sh/system-design