Alguns sistemas simplesmente não podem falhar. Sistemas financeiros, de saúde, infraestrutura crítica — quando performance degrada ou sistema cai, as consequências vão além de usuários insatisfeitos. Este artigo explora práticas de performance para sistemas de missão crítica.
Em sistemas críticos, "funcionando" não é suficiente. Precisa funcionar bem, sempre, sob qualquer condição.
Características de Sistemas Críticos
Requisitos típicos
Disponibilidade: 99.99% (52 min downtime/ano)
Latência p99: < 50ms
Taxa de erro: < 0.01%
Recovery time: < 30 segundos
Data loss: Zero
Exemplos
Financeiro: Trading, pagamentos, core banking
Saúde: Monitores de pacientes, prescrições
Infraestrutura: Energia, telecom, transporte
Governo: Eleições, emergência, defesa
Princípios Fundamentais
1. Defense in Depth
Múltiplas camadas de proteção:
Camada 1: Validação de entrada
Camada 2: Timeouts e circuit breakers
Camada 3: Redundância de serviços
Camada 4: Replicação de dados
Camada 5: Disaster recovery
2. Fail-Safe Defaults
# ❌ Falha silenciosa
def process_payment(payment):
try:
return gateway.charge(payment)
except Exception:
return None # Ignora erro
# ✅ Falha segura e explícita
def process_payment(payment):
try:
result = gateway.charge(payment)
if not result.is_verified():
raise PaymentVerificationFailed()
return result
except Exception as e:
log_critical(e)
alert_oncall()
raise PaymentProcessingError(original=e)
3. Graceful Degradation
def get_user_recommendations(user_id):
try:
# Tentar serviço completo
return recommendation_service.get_personalized(user_id)
except TimeoutError:
# Fallback: cache local
cached = local_cache.get(user_id)
if cached:
return cached
# Fallback: populares genéricos
return get_popular_items()
Patterns para Alta Performance
1. Active-Active Redundancy
Primary Region: us-east-1
Load: 50%
Status: Active
Secondary Region: us-west-2
Load: 50%
Status: Active
Failover: Automatic via DNS
RTO: 30 seconds
RPO: 0 (sync replication)
2. Read-Write Separation
class Database:
def __init__(self):
self.primary = connect_primary()
self.replicas = connect_replicas()
def write(self, query):
return self.primary.execute(query)
def read(self, query):
replica = self.load_balance(self.replicas)
return replica.execute(query)
3. Request Hedging
async def critical_query(query):
"""
Envia para múltiplas réplicas, usa primeira resposta
"""
tasks = [
replica.execute(query)
for replica in replicas[:3]
]
# Retorna primeiro resultado
done, pending = await asyncio.wait(
tasks,
return_when=FIRST_COMPLETED
)
# Cancela queries pendentes
for task in pending:
task.cancel()
return done.pop().result()
4. Pre-computation
# Pré-calcular resultados críticos
@scheduled(every='5 minutes')
def precompute_dashboards():
for user in premium_users:
dashboard_data = compute_dashboard(user)
cache.set(f'dashboard:{user.id}', dashboard_data)
# Request apenas busca do cache
def get_dashboard(user_id):
return cache.get(f'dashboard:{user_id}')
Testando Sistemas Críticos
Chaos Engineering
# Chaos Monkey: mata instâncias aleatórias
def chaos_test():
instance = random.choice(production_instances)
instance.terminate()
assert system_health() == 'healthy'
assert latency_p99() < SLO
# Chaos Kong: simula falha de região
def region_failover_test():
disable_region('us-east-1')
assert all_requests_succeed()
assert latency_increase() < 20%
Game Days
## Game Day Plan: DB Failover
### Objetivo
Validar que failover de DB ocorre < 30s sem perda de dados
### Pré-requisitos
- [ ] Backup verificado
- [ ] Runbook atualizado
- [ ] On-call alertado
### Execução
1. 10:00 - Iniciar monitoramento
2. 10:05 - Simular falha de primary
3. 10:06 - Verificar failover automático
4. 10:10 - Validar integridade de dados
5. 10:15 - Restaurar primary
6. 10:20 - Verificar failback
### Métricas
- Tempo de failover: ___s
- Requests perdidos: ___
- Dados perdidos: ___
### Resultado
[ ] Passou [ ] Falhou
Load Testing Extremo
# Teste além do esperado
Cenários:
Normal: 1x load
Pico: 5x load
Extremo: 10x load
Absurdo: 20x load
Para cada cenário:
- Latência ainda dentro do SLO?
- Erros ainda dentro do SLO?
- Sistema se recupera quando carga diminui?
- Quanto tempo para recuperação?
Monitoramento de Sistemas Críticos
Golden Signals com SLOs rigorosos
Latency:
p50: < 20ms
p95: < 50ms
p99: < 100ms
p99.9: < 500ms
Traffic:
Expected: 10,000 req/s
Alert: < 8,000 or > 15,000
Errors:
Total: < 0.01%
5xx: < 0.001%
Saturation:
CPU: < 60%
Memory: < 70%
Connections: < 80%
Alertas Multi-nível
# Tier 1: Ação imediata (página)
- alert: CriticalLatency
expr: latency_p99 > 100ms
for: 1m
severity: page
# Tier 2: Investigar logo (ticket urgente)
- alert: HighLatency
expr: latency_p99 > 50ms
for: 5m
severity: ticket_urgent
# Tier 3: Monitorar (ticket normal)
- alert: ElevatedLatency
expr: latency_p99 > 30ms
for: 15m
severity: ticket
Dashboards de War Room
┌─────────────────────────────────────────────────┐
│ SYSTEM STATUS: 🟢 HEALTHY │
├─────────────────────────────────────────────────┤
│ Latency p99: 32ms (SLO: 50ms) [==== ] │
│ Error Rate: 0.003% (SLO: 0.01%) [= ] │
│ Throughput: 12,342 req/s [====== ] │
│ CPU: 45% [==== ] │
├─────────────────────────────────────────────────┤
│ Active Incidents: 0 │
│ Error Budget Remaining: 87% │
│ Last Incident: 14 days ago │
└─────────────────────────────────────────────────┘
Runbooks para Incidentes
Estrutura
## Runbook: High Latency Alert
### Sintomas
- Latência p99 > 50ms por > 1 minuto
- Alerta: CriticalLatency
### Impacto
- Usuários experimentam lentidão
- Possível timeout em clientes
- SLO em risco
### Diagnóstico
1. Verificar dashboard: grafana.internal/critical
2. Identificar componente lento:
kubectl top pods -n production
3. Verificar dependências:
curl -s http://health.internal/dependencies
### Mitigação
**Se CPU alta:**
- Escalar horizontalmente: `kubectl scale deployment/api --replicas=10`
**Se DB lento:**
- Verificar queries: `SELECT * FROM pg_stat_activity`
- Considerar failover para replica
**Se dependência externa:**
- Ativar circuit breaker: `curl -X POST http://api/circuit/external/open`
### Escalação
- 5 min sem resolução: Chamar lead de plantão
- 15 min sem resolução: Chamar gerente de engenharia
- 30 min sem resolução: Acionar war room
Práticas Organizacionais
On-call Structure
Primary: Responde em 5 min
Secondary: Backup se primary não responder em 10 min
Tertiary: Especialista para casos complexos
Rotação: Semanal
Compensação: Dia de folga por semana de plantão
Post-incident Review
## Incident Review: 2025-01-15 Latency Spike
### Sumário
Latência p99 atingiu 2s por 15 minutos devido a query N+1
introduzida em deploy às 14:30.
### Timeline
- 14:30 - Deploy da versão 2.3.1
- 14:45 - Primeiro alerta de latência
- 14:47 - On-call iniciou investigação
- 15:00 - Identificada query N+1
- 15:05 - Rollback iniciado
- 15:08 - Sistema normalizado
### Impacto
- 15 minutos de degradação
- 0.5% de requests com timeout
- 0 perda de dados
### Root Cause
Query N+1 introduzida em PR #1234, não detectada em review
ou testes de performance.
### Ações
1. [ ] Adicionar teste de performance para endpoint afetado
2. [ ] Implementar detecção automática de N+1 em CI
3. [ ] Revisar checklist de code review
### Lições
- Mudanças em queries críticas precisam de load test
- Alertas funcionaram bem
- Rollback foi rápido e efetivo
Conclusão
Performance em sistemas críticos exige:
- Redundância em todas as camadas
- Fail-safe por padrão
- Testes extremos (chaos, game days)
- Monitoramento obsessivo
- Runbooks detalhados
- Cultura de blameless post-mortems
A diferença entre sistema crítico e não-crítico não é só técnica:
Não-crítico: "Se falhar, usuários reclamam"
Crítico: "Se falhar, consequências são irreversíveis"
Planeje para o pior caso. Teste o impensável. Documente tudo.
Em sistemas críticos, paranoia é feature, não bug.