System Design — Camada de Coleta (Collector)
CDN/Edge, Gateway/LB, Collector /collect, LGPD gate. A porta de entrada.
Definição
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 → Solução
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.Dica de entrevista
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.Código
// 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
})Perguntas de entrevista
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← →