R
Interview Deckreact · next.js · senior/staff
0·0·122
System Design

System Design — Camada de Coleta (Collector)

CDN/Edge, Gateway/LB, Collector /collect, LGPD gate. A porta de entrada.

A camada de coleta recebe os eventos do cliente e os entrega ao broker. Componentes: (1) CDN/Edge — recebe no PoP mais próximo do usuário. (2) API Gateway / LB — termina TLS, rate limiting, autoscaling. (3) Collector — endpoint HTTP /collect que valida formato, autentica origem, e responde 204 rapidamente. (4) Consent LGPD gate — antes de aceitar o evento, confere consentimento; sem consentimento, descarta ou anonimiza.

Problema
Collector que faz muito (enriquecimento, persistência, query) não aguenta milhões de req/s. Sem rate limit, abuso/DDoS derruba o sistema. Sem consent gate, viola LGPD.
Solução
Collector leve de propósito: valida formato básico, autentica, checa consent, publica no broker, responde 204. Nada de processar dado pesado. Stateless = escala horizontal. Rate limit no Gateway por origem. Consent é regra de negócio que vai antes de qualquer escrita.
Tip
O collector responde 204 (No Content) em vez de 200. Não precisa retornar nada — apenas confirmar recebimento. Menos bytes, menos latência. Idealmente o p99 do collector é < 50ms.
// Collector em Node.js — exemplo
import express from 'express'
import { Kafka } from 'kafkajs'

const app = express()
const kafka = new Kafka({ brokers: ['kafka:9092'] })
const producer = kafka.producer()

app.post('/collect', async (req, res) => {
  // 1. Validação leve
  const events = req.body
  if (!Array.isArray(events)) return res.status(400).end()

  // 2. Consent LGPD
  if (!hasConsent(req.cookies)) {
    return res.status(204).end()  // aceita mas descarta
  }

  // 3. Autenticação por origem
  const origin = req.headers.origin
  if (!ALLOWED_ORIGINS.includes(origin)) {
    return res.status(403).end()
  }

  // 4. Enriquecimento mínimo (server timestamp, IP geo)
  const enriched = events.map(e => ({
    ...e,
    server_timestamp: Date.now(),
    geo: lookupGeo(req.ip),
  }))

  // 5. Publica no Kafka (particiona por session_id)
  await producer.send({
    topic: 'events.raw',
    messages: enriched.map(e => ({
      key: e.session_id,
      value: JSON.stringify(e),
    })),
  })

  res.status(204).end()  // responde rápido
})
Q.Por que o collector deve responder 204 rápido?
A.O cliente está esperando para liberar a fila local. Quanto mais rápido o collector responde, menos memória do browser fica ocupada com a fila e menor a chance de perder evento se a aba fechar. 204 (No Content) é o status correto: recebido com sucesso, sem body de resposta.
Q.Como o collector escala horizontalmente?
A.Stateless: não guarda nada localmente, todo evento vai para o broker (Kafka). Atrás de um Load Balancer com autoscaling baseado em CPU/requests. Cada instância é idêntica e descartável. Se uma cai, o LB redireciona para outra sem perda.
Q.Como implementar consent LGPD no collector?
A.Cookie de consent enviado no request. Se ausente ou negado: descarta evento (response 204 mesmo assim, sem persistir). Se parcial: anonimiza PII (hash do user_id, remove IP). Política de retenção: dados crus expiram em N dias automaticamente no S3 via lifecycle policy.
106/122← →