Como aplicar chaos engineering para validar resiliência
1. Fundamentos do Chaos Engineering e sua relevância para resiliência
Chaos Engineering é a disciplina de experimentar em um sistema distribuído para construir confiança na capacidade do sistema de suportar condições turbulentas em produção. Diferentemente de testes tradicionais (unitários, integração, fim a fim), que verificam comportamentos esperados sob condições controladas, o Chaos Engineering introduz intencionalmente falhas para descobrir fraquezas antes que elas se manifestem como incidentes reais.
Os princípios fundamentais do Chaos Engineering, definidos pelo Principles of Chaos Engineering, incluem:
- Definir o estado estável do sistema: medir métricas como latência, taxa de erro e throughput
- Hipótese sobre estado estável: formular uma hipótese clara sobre o comportamento esperado do sistema diante de uma falha
- Variáveis do mundo real: simular falhas reais como falhas de rede, picos de tráfego, falhas de hardware
- Experimentar em produção: realizar experimentos controlados no ambiente de produção (ou staging realista)
Para sistemas distribuídos e microsserviços, onde a complexidade das interações entre componentes torna impossível prever todos os cenários de falha, o Chaos Engineering é essencial. Ele expõe pontos cegos em estratégias de resiliência, como timeouts mal configurados, circuit breakers ineficazes ou dependências não tratadas.
2. Preparação do ambiente e definição de hipóteses de resiliência
Antes de qualquer experimento, é necessário mapear as dependências críticas do sistema. Um diagrama de arquitetura deve identificar:
Serviço A (API Gateway) → Serviço B (Autenticação) → Banco de Dados MySQL
Serviço A → Serviço C (Catálogo) → Cache Redis
Serviço A → Serviço D (Pagamento) → API Externa (Gateway de Pagamento)
Serviço E (Notificações) → Fila RabbitMQ
Com base nesse mapeamento, estabeleça métricas de estado estável. Exemplo de SLOs:
Métrica de estado estável:
- Latência p95: < 200ms
- Taxa de erro: < 0.1%
- Throughput: > 1000 req/s
- Disponibilidade: > 99.9%
Formule hipóteses específicas e mensuráveis. Exemplo:
Hipótese: "Se o banco de dados MySQL ficar indisponível por 30 segundos,
o serviço de autenticação deve retornar erro 503 (Service Unavailable)
para novas requisições, sem corromper sessões existentes ou perder dados.
A latência p95 não deve exceder 500ms durante o período de falha."
3. Ferramentas e técnicas para execução de experimentos de caos
As ferramentas mais populares incluem:
- Chaos Monkey (Netflix): encerra instâncias aleatoriamente para testar tolerância a falhas
- Gremlin: plataforma completa com injeção de falhas de rede, CPU, memória, disco
- Litmus: framework open-source para Kubernetes, com suporte a workflows de caos
- Chaos Mesh: ferramenta nativa Kubernetes para simular falhas de pod, rede, disco
Tipos de experimentos comuns:
1. Falha de rede: latência adicional (100ms, 500ms), perda de pacotes (10%, 50%)
2. Falha de nó: kill de processo (SIGKILL), desligamento de container
3. Falha de recurso: stress de CPU (80%, 100%), consumo de memória, disco cheio
4. Falha de dependência: desconexão de banco de dados, falha de API externa
Automação com CI/CD:
Pipeline de experimento:
1. Deploy da aplicação em staging
2. Execução de testes de carga (baseline)
3. Injeção de falha controlada (ex.: desconexão Redis)
4. Monitoramento de métricas (5 minutos)
5. Rollback automático se métricas violarem SLOs
6. Geração de relatório de hipóteses
4. Execução prática de um experimento de Chaos Engineering
Vamos executar um experimento prático: desconexão do banco de dados MySQL do serviço de autenticação.
Passo 1: Escolher a falha e definir escopo
Falha: Desconexão da conexão TCP com MySQL (porta 3306)
Escopo: 30% das requisições para o endpoint /auth/login
Duração: 60 segundos
Ambiente: Staging (réplica de produção)
Passo 2: Executar o experimento
Usando Chaos Mesh (Kubernetes):
# Configuração do experimento de falha de rede
apiVersion: chaos-mesh.org/v1alpha1
kind: NetworkChaos
metadata:
name: mysql-disconnect
spec:
action: partition
mode: fixed-percent
value: "30"
selector:
namespaces:
- staging
labelSelectors:
app: auth-service
direction: both
target:
mode: all
selector:
namespaces:
- staging
labelSelectors:
app: mysql
duration: "60s"
Passo 3: Monitoramento em tempo real
Dashboards devem mostrar:
Métrica | Antes (baseline) | Durante falha | Após recuperação
Latência p95 (ms) | 45 | 320 | 48
Taxa de erro (%) | 0.02 | 18.5 | 0.03
Throughput (req/s) | 850 | 620 | 840
Sessões ativas | 2340 | 2280 | 2335
Passo 4: Análise de resultados
Hipótese validada? PARCIALMENTE
- O serviço retornou 503 corretamente para novas requisições
- Sessões existentes foram mantidas (usando cache local)
- Porém, a latência p95 atingiu 320ms (acima do limite de 200ms)
- A taxa de erro foi de 18.5% (acima do limite de 0.1%)
- Descoberta: o timeout de conexão com MySQL estava configurado para 30s
(muito alto), causando retenção de threads e degradação de performance
5. Estratégias para mitigação de falhas descobertas
Com base no experimento, implemente correções:
1. Circuit Breaker (Resilience4j):
- Configurar circuit breaker para MySQL com limiar de 50% de erros
- Timeout de 2s, janela de 10s, half-open após 5s
2. Retry com backoff exponencial:
- Máximo de 3 tentativas, backoff inicial de 100ms
- Jitter de 50ms para evitar thundering herd
3. Bulkhead:
- Limitar conexões simultâneas com MySQL a 20 threads
- Pool separado para operações críticas vs. não críticas
4. Fallback:
- Cache local (Caffeine) com TTL de 30s para dados de autenticação
- Modo offline para funcionalidades não essenciais
Exemplo de configuração Resilience4j:
resilience4j.circuitbreaker:
instances:
mysqlAuth:
slidingWindowSize: 10
failureRateThreshold: 50
waitDurationInOpenState: 5000
permittedNumberOfCallsInHalfOpenState: 3
minimumNumberOfCalls: 5
timeoutDuration: 2000ms
6. Evolução contínua e cultura de Chaos Engineering
O Chaos Engineering não é um projeto único, mas um ciclo contínuo:
Ciclo de experimentos (recomendação):
- Semanal: experimentos simples (falha de um pod, latência de rede)
- Mensal: experimentos complexos (falha de banco, queda de região)
- Trimestral: Game Day completo (simulação de desastre com equipe)
Game Day típico:
1. Sexta-feira, 14h-17h (horário de baixo tráfego)
2. Cenário: "O provedor de nuvem da região US-East caiu"
3. Equipes on-call e SRE participam ativamente
4. Documentação em tempo real no runbook
5. Retrospectiva na segunda-feira seguinte
Documentação de lições aprendidas:
Lições documentadas após experimento:
1. Timeout de conexão MySQL reduzido de 30s para 2s
2. Circuit breaker implementado para todas as dependências externas
3. Cache local adicionado para dados de sessão
4. Runbook atualizado com procedimento de failover manual
5. Métrica de "tempo de recuperação" adicionada ao dashboard
7. Boas práticas e armadilhas comuns
Boas práticas:
✓ Comece em staging, evolua para produção gradualmente
✓ Tenha observabilidade completa (métricas, logs, tracing)
✓ Defina blast radius (escopo limitado a 10-30% do tráfego)
✓ Automatize rollback com base em métricas de SLO
✓ Obtenha aprovação de stakeholders para experimentos em produção
✓ Promova segurança psicológica: "falhas são aprendizado, não culpa"
Armadilhas comuns:
✗ Realizar experimentos sem hipóteses claras
✗ Ignorar métricas de estado estável (não saber o que é "normal")
✗ Experimentar em produção sem rollback automático
✗ Executar experimentos em horários de pico sem comunicação prévia
✗ Confundir Chaos Engineering com "quebrar tudo de propósito" (falta de foco)
✗ Não documentar descobertas e lições aprendidas
Chaos Engineering, quando aplicado corretamente, transforma a resiliência de sistemas distribuídos de uma esperança em uma propriedade mensurável e continuamente validada.
Referências
- Principles of Chaos Engineering — Documento fundamental que define os princípios e a metodologia do Chaos Engineering
- Gremlin Blog: Chaos Engineering Best Practices — Guia prático com exemplos de experimentos, métricas e armadilhas comuns
- Chaos Mesh Documentation — Documentação oficial da ferramenta open-source para Kubernetes, com exemplos de configuração de experimentos
- Resilience4j Documentation — Documentação oficial da biblioteca de resiliência para Java, incluindo circuit breakers, retries e bulkheads
- Netflix Tech Blog: Chaos Monkey — Artigo original da Netflix sobre Chaos Monkey, o precursor do Chaos Engineering moderno
- LitmusChaos Docs — Documentação oficial do framework de Chaos Engineering para Kubernetes, com workflows e integração CI/CD
- AWS Well-Architected Framework: Reliability Pillar — Guia da AWS sobre práticas de resiliência e testes de falhas em arquiteturas cloud