Este backend eu construí do zero e hoje passa de 1k commits. Ele roda em um domínio sensível (fluxos de mídia e gestão administrativa em ambiente hospitalar), integra com serviços externos, expõe rotas públicas e um backoffice com RBAC. O que segura a operação não é milagre nem framework: são decisões pequenas, consistentes, e um cuidado quase obsessivo com latência, carga e custo por request.
20M+
Requests/mês
6ms
Latência
92%
Cache hit
1k+
Commits
Contexto real (não de laboratório)
Escolhi Fiber sobre fasthttp para privilegiar throughput e previsibilidade. O sistema precisa lidar com:
- Integração com APIs externas de catálogo/streaming e autenticação.
- Camada administrativa com JWT por cookie e controle fino de permissões.
- Observabilidade detalhada para explicar o que acontece, não só mostrar gráfico bonito.
- Cache híbrido para reduzir custo no read path e evitar dependência total do Redis.
Arquitetura que aguenta a pressão
O bootstrap é curto, mas cada linha tem motivo. No start eu:
- 1Ajusto GOMAXPROCS de acordo com o número de CPUs.
- 2Subo o GC percent e limito threads para reduzir overhead em pico.
- 3Inicializo pool de conexões Postgres com limites e health checks.
- 4Inicio cache (Redis + fallback local) e programo limpeza periódica.
- 5Ativo métricas e dashboard interno para observabilidade contínua.
- 6Inicio o servidor com timeouts e limites agressivos.
Na borda HTTP, o Fiber roda com body limit, buffers bem definidos, timeouts e concorrência calculada por CPU. Isso corta o efeito de fila infinita quando o load vira spike. Outro detalhe que eu não abro mão: o servidor não só expõe métricas, ele observa CPU, heap e goroutines. Isso fecha o ciclo de diagnóstico, e evita conclusões erradas quando o gráfico sobe sem explicação.
Performance sem truques
Em Go, performance de verdade não é só handler rápido. O que fez diferença:
- JSON de alta performance com Sonic, validação controlada e buffer pool para reduzir alocação.
- HTTP client com pooling, timeouts e tentativas controladas para evitar travas em API lenta.
- Streaming de request body e compressão de resposta com ETag no pipeline.
- Timeouts com intenção: read/write/idle agressivos para matar conexão zumbi cedo.
- Pool de banco com limites claros para não colapsar quando o tráfego dobra.
Cache em camadas, porque Redis falha
Cache não é luxo, é linha de defesa. O desenho ficou assim:
- Redis como cache primário com expiração controlada.
- Fallback local em memória quando o Redis falha, mantendo disponibilidade.
- TTL cache para dados muito acessados (ex: mídia filtrada) e janelas curtas.
- Limpeza programada para evitar acúmulo e corrigir edge cases.
A diferença é simples: eu não quis ficar refém de um único componente. Quando Redis oscila, o sistema continua respondendo, só com menor hit rate. Isso salva incidentes.
Observabilidade que explica, não enfeita
Métrica sem contexto vira superstição. Eu montei uma stack que cobre:
- Contadores e histogramas de latência por rota.
- Tamanho de request/response para detectar payloads anormais.
- Cache hit/miss e latência de chamadas externas.
- Erros de negócio e sucesso por operação.
- CPU, heap, goroutines, GC e sinais de estresse do runtime.
Um detalhe técnico que me salvou: rotas são normalizadas antes de virar label, reduzindo a explosão de séries. Sem isso, Prometheus vira um buraco negro de séries. E por cima disso ainda tenho um middleware de validação de resposta, que avisa quando um JSON válido chega com campos nulos inesperados. Esse tipo de alerta impede regressão silenciosa.
Segurança sem fricção
A área admin usa JWT em cookie seguro (HTTPOnly + SameSite) com RBAC por permissão explícita. Isso me deu:
- Separação clara de poderes entre perfis.
- Trilha de auditoria para operações administrativas.
- Endpoints sensíveis protegidos sem poluir handlers com ifs.
Em ambiente de desenvolvimento, pprof habilitado para diagnóstico. Em produção, headers de segurança e políticas mais rígidas.
Erros que quase me custaram caro
O aprendizado de verdade vem de onde dói:
- Cardinalidade alta em métricas derrubou meu monitoramento; normalizar rotas resolveu.
- Dependência total do Redis criou ponto único de falha; o fallback local manteve a API viva.
- Sem tuning de GC, picos de tráfego geravam pausas; ajustar GOMAXPROCS e GC estabilizou.
- Retries cegos em APIs externas criaram tempestade; controlar tentativas e timeout foi decisivo.
- Log verboso em produção virou gargalo; logging assíncrono e seletivo reduziu custo.
Checklist do que realmente segura produção
- Cache híbrido com TTL e fallback local.
- Observabilidade de latência, payload e runtime.
- Pool de conexões com limites e health check.
- JSON rápido, validado e com buffers reutilizáveis.
- Normalização de rotas para não explodir o número de séries.
Roberto de Moraes
Gerente de TI & Engenheiro de Software · Go · Next.js · Kotlin · AWS · GCP
Entrar em contato