TRILHA 1 · FUNDAMENTOS Teoria

🔒 Qualidade e Atributos de Qualidade

Performance, segurança, disponibilidade — os -ilities que definem o sucesso de uma arquitetura. Cada decisão arquitetural é um trade-off entre esses atributos.

7
Tópicos
35 min
Duração
Básico
Nível
1.4
Módulo
1

⚡ Performance

Cada 100ms a mais no carregamento reduz conversão em 1% (Amazon). Performance não é sobre ser rápido — é sobre atender expectativas mensuradas em percentis: P50, P95, P99.

📚

Conceito — Latência vs Throughput

Latência

Tempo que uma única requisição leva do início ao fim. Medida em milissegundos. É o que o usuário sente.

GET /api/users → 45ms

Throughput

Quantidade de requisições processadas por unidade de tempo. Medido em RPS (requests per second). É o que o sistema aguenta.

12.000 RPS no pico
Cuidado: Otimizar latência pode reduzir throughput e vice-versa. Um cache reduz latência mas pode ser bottleneck de throughput se o cache server não escalar.
📊

Dados — Números que Importam

100ms
= -1% conversão (Amazon)
1s
= -7% conversão (Walmart)
3s
= 53% abandono mobile (Google)

Percentis explicados

P50 Mediana — 50% das requisições são mais rápidas que esse valor. O “caso típico”.
P95 95% estão abaixo. Mostra como é a experiência para a maioria dos usuários.
P99 O “tail latency” — 1% pior. Frequentemente são seus maiores clientes (mais dados).
💡

Dica Prática — Caching Strategies

🌐 CDN Cache

Assets estáticos (imagens, JS, CSS) na borda. CloudFront, Cloudflare. Reduz latência global.

⚡ Application Cache

Redis/Memcached para dados quentes. Cache de queries, sessões, resultados computados. TTL inteligente.

🖥️ Database Cache

Query cache, materialized views, read replicas. Reduz carga no banco primário.

✅ Fazer

  • Medir antes de otimizar (profile first)
  • Definir SLAs com P95/P99, não média
  • Implementar cache em camadas (CDN → app → DB)
  • Usar load testing regularmente (k6, Locust)

❌ Evitar

  • Otimizar prematuramente sem dados
  • Usar média como métrica principal (esconde outliers)
  • Cache sem estratégia de invalidação
  • Ignorar tail latency (P99) — afeta seus maiores clientes
2

📈 Escalabilidade

Instagram escalou de 0 a 30 milhões de usuários em 2 anos com apenas 3 engenheiros. A chave? Decisões arquiteturais que permitiam crescer sem reescrever.

📚

Conceito — Vertical vs Horizontal

⬆️ Escalar Verticalmente (Scale Up)

Adicionar mais recursos à mesma máquina: mais CPU, RAM, SSD. Simples, mas tem teto físico e custo exponencial.

4 vCPU → 16 vCPU → 64 vCPU → 💰💰💰

↔️ Escalar Horizontalmente (Scale Out)

Adicionar mais instâncias iguais atrás de um load balancer. Escala “infinita”, mas exige arquitetura stateless.

1 server → 3 servers → 50 servers → auto-scaling
🕐

Timeline — Passos para Escalar

1

Otimizar o que existe

Indexar queries, adicionar cache, otimizar código. 80% dos problemas resolvem aqui.

2

Scale up (vertical)

Trocar a máquina por uma maior. Rápido, sem mudança de código. Funciona até certo ponto.

3

Read replicas + CDN

Separar leitura de escrita. Servir estáticos via CDN. Reduzir carga no primário.

4

Scale out (horizontal)

Tornar serviços stateless, load balancer, auto-scaling groups. Exige refatorar estado.

5

Sharding + decomposição

Particionar dados, quebrar em microsserviços. Último recurso — complexidade alta.

📊

Case — Instagram (2010-2012)

3
engenheiros
30M
usuários em 2 anos
$1B
aquisição pelo Facebook
Stack: Python/Django + PostgreSQL + Redis + Memcached + S3. Nada exotérico. O segredo foi manter stateless, cachear agressivamente e usar tecnologias proven com excelente scaling path.
3

🛡️ Segurança

O breach da Equifax (2017) expôs dados de 147 milhões de pessoas por um patch não aplicado. Custou US$ 700M em multas. Segurança não é feature — é atributo fundamental.

📚

Conceito — OWASP Top 10 e Zero Trust

OWASP Top 10

As 10 vulnerabilidades mais críticas em aplicações web. Atualizado periodicamente.

  • • Broken Access Control
  • • Cryptographic Failures
  • • Injection (SQL, NoSQL, OS)
  • • Insecure Design
  • • Security Misconfiguration

Zero Trust Architecture

“Nunca confie, sempre verifique.” Nenhum request é confiável por padrão, mesmo vindo da rede interna.

  • • Autenticar todo request
  • • Least privilege por padrão
  • • Encrypt tudo (at rest + in transit)
  • • Monitorar e auditar continuamente
  • • Micro-segmentação de rede
⚠️

Alerta — Consequências de Falhas de Segurança

Equifax (2017)

147M registros expostos. Patch de Apache Struts não aplicado. US$ 700M em multas.

Yahoo (2013-2014)

3 bilhões de contas comprometidas. Preço de venda caiu US$ 350M na aquisição pela Verizon.

SolarWinds (2020)

Supply chain attack atingiu 18.000+ organizações incluindo governo dos EUA. Impacto imensurável.

✅ Fazer

  • Security by design desde o dia 1
  • Encrypt at rest e in transit (TLS 1.3)
  • Principle of Least Privilege em tudo
  • Automated security scanning no CI/CD

❌ Evitar

  • “Vamos adicionar segurança depois”
  • Secrets no código ou repositório Git
  • Confiar em validação apenas no frontend
  • Ignorar dependências desatualizadas
4

✅ Disponibilidade

99.9% parece excelente até você calcular: são 8.7 horas de downtime por ano. Quando o AWS S3 caiu por 4h em 2017, derrubou metade da internet junto — Netflix, Slack, Trello.

📚

Conceito — SLA / SLO / SLI

SLI

Service Level Indicator

A métrica real medida. Ex: “99.95% dos requests responderam em <200ms”.

SLO

Service Level Objective

A meta interna. Ex: “Queremos 99.9% de disponibilidade”. Mais rigoroso que o SLA.

SLA

Service Level Agreement

O contrato com o cliente. Se violar, há penalidades (créditos, multas). Sempre abaixo do SLO.

📊

Dados — A Tabela dos “Noves”

Disponibilidade Downtime/ano Downtime/mês Exemplo
99% 3.65 dias 7.3h Sistemas internos
99.9% 8.7h 43.8min SaaS típico
99.99% 52.6min 4.4min E-commerce grande
99.999% 5.3min 26s Financeiro / saúde
Regra: Cada “9” adicional custa ~10x mais em infra e engenharia. Escolha o nível que o negócio realmente precisa.
💡

Dica Prática — Circuit Breaker Pattern

Quando um serviço dependente falha, o circuit breaker “abre o circuito” e retorna fallback imediatamente, evitando cascata de falhas.

CLOSED

Normal. Requests passam. Monitorando falhas.

OPEN

Muitas falhas. Requests bloqueados. Retorna fallback.

HALF-OPEN

Testando. Permite poucos requests para verificar recuperação.

Implementações: Resilience4j (Java), Polly (.NET), Hystrix (legado), ou nativo em service meshes como Istio.

5

🔧 Manutenibilidade

O Google estima que 70% do custo de software está na manutenção, não no desenvolvimento inicial. Código é escrito uma vez e lido centenas de vezes — readability > cleverness.

📚

Conceito — Readability > Cleverness

Operabilidade

Facilidade de operar em produção. Deploy automatizado, rollback rápido, logs claros, runbooks documentados.

Simplicidade

Remover complexidade acidental. Abstrações claras, sem herança profunda, nomes que comunicam intenção.

Evolvabilidade

Facilidade de mudar requisitos. Arquitetura modular, interfaces bem definidas, testes que dão confiança para refatorar.

Métricas de Qualidade

Cyclomatic complexity, cognitive complexity, code churn, time-to-fix. Medir é o primeiro passo para melhorar.

✅ Fazer

  • Code review como prática sagrada
  • Refactoring contínuo (Boy Scout Rule)
  • Nomes descritivos > comentários
  • Documentar decisões (ADRs)

❌ Evitar

  • “Clever code” que só o autor entende
  • Funções com 500+ linhas
  • Dívida técnica sem tracking
  • “Vou arrumar depois” sem criar issue
💡

Dica Prática — Regra do Teto de 20%

Reserve 20% de cada sprint para pagar dívida técnica. Não negocie isso. Times que ignoram dívida técnica vêem a velocidade cair a cada sprint até quase parar. O Google, Spotify e Nubank praticam isso sistematicamente.

6

🔍 Observabilidade

Os 3 pilares da observabilidade. O Stripe usa distributed tracing para acompanhar cada requisição de pagamento por 15+ serviços — sem isso, debugar levaria horas em vez de minutos.

📚

Conceito — Os 3 Pilares

📜 Logs

Eventos discretos com timestamp. O “diário” do sistema.

Ferramenta: ELK Stack, Loki

Dica: Logs estruturados (JSON) > texto livre

📈 Métricas

Valores numéricos ao longo do tempo. Ideais para alertas e dashboards.

Ferramenta: Prometheus + Grafana

Tipos: Counter, Gauge, Histogram, Summary

🔗 Traces

Caminho de um request através de múltiplos serviços. Essencial em microsserviços.

Ferramenta: Jaeger, OpenTelemetry

Chave: Correlation ID propagado entre serviços

🕐

Timeline — Implementando Observabilidade

1

Logs estruturados

Comece com JSON logs. Inclua request_id, user_id, action, duration. Centralize com ELK ou Loki.

2

Métricas RED/USE

RED (Rate, Errors, Duration) para serviços. USE (Utilization, Saturation, Errors) para recursos. Prometheus + Grafana.

3

Distributed tracing

OpenTelemetry como padrão. Propagar trace context entre serviços. Visualizar com Jaeger ou Tempo.

4

Alerting inteligente

Alertas baseados em sintomas (SLO burn rate), não causas. Evitar alert fatigue. PagerDuty ou OpsGenie.

📊

Dados — Impacto da Observabilidade

90%
redução no MTTR com tracing (Stripe)
15+
serviços monitorados por request (Stripe)
73%
das empresas adotam OpenTelemetry (CNCF 2024)
7

🔄 Testabilidade

Nubank tem 90%+ de cobertura em Clojure porque a arquitetura facilita: funções puras, imutabilidade, injeção de dependência em todo lugar. Se testar é difícil, o time para de testar.

📚

Conceito — Pirâmide de Testes

E2E
Poucos, lentos, caros
Integração
Médios, testam contratos
Unitários
Muitos, rápidos, baratos

Unitários (~70%)

Testam funções/classes isoladas. Millisegundos para rodar. Sem dependências externas.

Integração (~20%)

Testam interação entre componentes. API + banco, serviço A + serviço B. Testcontainers.

E2E (~10%)

Fluxo completo do usuário. Lentos, frágeis, mas essenciais para caminhos críticos. Playwright, Cypress.

✅ Fazer

  • Design for testability (DI, interfaces, funções puras)
  • Testes rodam no CI a cada push
  • Contract testing entre serviços (Pact)
  • Mutation testing para validar qualidade dos testes

❌ Evitar

  • Pirâmide invertida (muitos E2E, poucos unitários)
  • Testes que dependem de ordem de execução
  • Mockar tudo (testa implementação, não comportamento)
  • Cobertura como métrica de vaidade sem avaliar qualidade
💡

Dica Prática — Testcontainers + Arquitetura Hexagonal

Use Arquitetura Hexagonal (Ports & Adapters) para separar lógica de negócio de infraestrutura. O core é testável com mocks simples. A integração usa Testcontainers para subir banco e serviços reais em containers descartáveis.

Core (puro) → Ports (interfaces) → Adapters (implementações)
Testes unitários no Core | Testes integração nos Adapters

📋 Checklist do Módulo 1.4

Antes de seguir para o próximo módulo, verifique se você entende:

Próximo

🌐 Módulo 1.5 — Comunicação entre Sistemas

REST, GraphQL, gRPC, mensageria — como sistemas conversam