System Design/03 - Qualidade/Monitoring2 min
Health Monitoring
- Que problema isso resolve?
- Quando usar / quando NÃO usar?
- Qual o principal trade-off?
- Como isso falha em produção?
Conceito
Cada componente expõe seu próprio estado, permitindo que orquestrador, balanceador e operadores saibam quem está apto a receber tráfego. Ver Health Endpoint Monitoring para o padrão de implementação.
Os três tipos de probe
| Probe | Pergunta | Ação se falhar |
|---|---|---|
| Liveness | O processo está vivo? | Reinicia |
| Readiness | Está pronto para receber tráfego? | Tira da rotação (não reinicia) |
| Startup | Já terminou de inicializar? | Adia os outros probes |
Confundir liveness com readiness é o erro mais consequente: se o liveness verifica o banco e o banco fica lento, todas as instâncias reiniciam — transformando uma degradação em uma queda total.
Regra: liveness verifica só o processo. Readiness verifica as dependências.
Health check raso vs profundo
| Raso | Profundo | |
|---|---|---|
| Verifica | O processo responde | Banco, cache, dependências |
| Custo | Mínimo | Consulta real a cada check |
| Risco | Não detecta app quebrado | Propaga falha em cascata |
Trade-offs
Health check profundo tem um modo de falha traiçoeiro: se o serviço A verifica o serviço B em seu health check, e B fica lento, A é declarado doente e retirado da rotação — mesmo estando perfeitamente capaz de servir as requisições que não dependem de B. A falha de B vira falha de A por decisão do monitoramento.
A prática recomendada é distinguir dependência crítica de opcional, e reportar estado degradado em vez de binário:
{ "status": "degradado",
"banco": { "status": "ok", "latencia_ms": 3 },
"cache": { "status": "falha", "erro": "timeout" } }
Com cache fora, o serviço fica lento mas funcional — deve continuar recebendo tráfego.
Outro cuidado: health check não deve ser autenticado nem custoso, porque roda a cada poucos segundos por instância. Uma verificação que faz três consultas pesadas multiplicada por 50 instâncias vira carga significativa sobre o próprio banco que ela monitora.
Exemplo prático
GET /health/live → 200 se o processo responde. Nada mais.
GET /health/ready → 200 se banco OK e migrações aplicadas
→ 503 se dependência crítica falhou
Durante um deploy, a nova instância sobe: live responde imediatamente, mas ready só responde 200 depois que o pool de conexões aqueceu e o cache inicial carregou. O balanceador só manda tráfego quando ready passa.
Isso evita o sintoma clássico de deploy: as primeiras requisições da instância nova sofrendo timeout porque chegaram antes de ela estar realmente pronta.
Relacionado
Parte de Monitoring · roadmap.sh/system-design