Modos de falha
O cálculo de disponibilidade que todo mundo faz — três réplicas com 99% cada dão 99,9999% — assume que as falhas são independentes. Elas quase nunca são. Entender os modos de falha reais é o que separa redundância que funciona de redundância que só multiplica custo.
Falha independente é ficção conveniente
Seção intitulada “Falha independente é ficção conveniente”Três réplicas do mesmo serviço falham juntas por muitos motivos:
- Rodam na mesma zona de disponibilidade, e a zona caiu.
- Rodam a mesma versão, e a versão tem um bug de memória.
- Dependem do mesmo banco, do mesmo DNS, do mesmo provedor de identidade.
- Receberam a mesma configuração errada pelo mesmo pipeline.
- Foram derrubadas pelo mesmo pico de tráfego.
Isso é falha correlacionada, e ela domina a estatística real. As causas mais comuns de indisponibilidade em produção — mudança de configuração, deploy ruim, esgotamento de recurso compartilhado — atingem todas as réplicas ao mesmo tempo, porque as réplicas são idênticas de propósito.
A conclusão prática é desconfortável: redundância protege de falha de componente, não de falha de projeto. Só a separação em domínios de falha distintos (zonas, contas, versões, janelas de deploy) reduz a correlação.
Cascata e o efeito dominó
Seção intitulada “Cascata e o efeito dominó”Uma falha local vira global quando os componentes compartilham recursos e não se protegem uns dos outros:
banco fica lento → requisições demoram → threads/conexões ficam presas esperando → o pool esgota → o serviço deixa de responder até o que não usa o banco → o health check falha → o balanceador tira réplicas do rodízio → a carga se concentra nas que sobraram → elas também caemRepare que a causa inicial afetava uma fração das requisições, e o resultado foi indisponibilidade total. Os mecanismos que interrompem esse encadeamento — timeout, disjuntor, bulkhead, limite de taxa — são descritos em falha parcial.
Um detalhe importante: o health check pode acelerar a cascata. Se ele verifica uma dependência compartilhada, todas as réplicas ficam not ready ao mesmo tempo — e o balanceador remove um serviço que ainda serviria parte do tráfego.
Falha cinza: nem vivo nem morto
Seção intitulada “Falha cinza: nem vivo nem morto”O modo mais difícil de diagnosticar. O componente não caiu; ele responde — devagar, com erro intermitente, ou com dados errados.
Exemplos que aparecem em produção:
- Nó com disco degradado: escrita 50 vezes mais lenta, sem erro.
- Placa de rede com perda de pacotes: 2% de timeouts que ninguém correlaciona.
- Réplica de banco com atraso crescente: responde, com dados velhos.
- Instância com CPU throttled: responde, fora do SLO.
- Processo com vazamento de memória: funciona, degradando ao longo de horas.
Por que é difícil: o health check binário responde “vivo”, o failover automático não dispara, e o tráfego continua indo para um componente doente. O sistema não escolhe entre funcionar e não funcionar — ele fica num limbo que é pior que a queda limpa, porque não aciona nenhuma automação.
O que ajuda: health check que considera latência e taxa de erro, não só resposta; detecção passiva no balanceador (tirar do rodízio quem responde pior que os pares); comparação entre réplicas em vez de limiar absoluto; e a disposição de matar o componente suspeito em vez de investigar com ele no ar.
Colapso metaestável
Seção intitulada “Colapso metaestável”Um sistema pode entrar num estado em que continua quebrado mesmo depois de a causa original desaparecer.
O exemplo clássico: um pico de tráfego causa timeouts; os clientes tentam de novo; o retry dobra a carga; o pico passa, mas a carga de retry se mantém; o sistema não consegue se recuperar sozinho porque a própria tentativa de recuperação o mantém sobrecarregado.
Sinal característico: o tráfego voltou ao normal e o serviço continua fora. A saída costuma ser drástica — rejeitar carga agressivamente, esvaziar filas, reiniciar em ondas — e a prevenção é limitar retry, aplicar backoff com jitter e rejeitar carga antes de saturar (veja carga e fila).
Projetar para falhar bem
Seção intitulada “Projetar para falhar bem”Como nem toda falha é evitável, a qualidade da falha vira requisito:
- Falhe rápido em vez de travar. Timeout curto é melhor que espera infinita.
- Falhe parcialmente: degrade o acessório e preserve o essencial.
- Falhe de forma óbvia: erro claro, métrica que reflete o sintoma, alerta acionável.
- Falhe de forma reversível: rollback pronto, mudança em lote pequeno.
- Falhe sem correlacionar: distribua entre zonas, versões e janelas de deploy.
- Falhe seguro: na dúvida sobre autorização, negue.
E exercite: modo de falha que nunca foi provocado é hipótese. É exatamente para isso que existe o caos controlado — e a falha cinza é o cenário que mais recompensa o exercício, porque é o que a automação normal não pega.