Pular para o conteúdo principal
Voltar aos insights

Case técnico · Engenharia de backend

Go em produção: arquitetura, cache e operação

As escolhas de arquitetura, cache e observabilidade no backend Go do Hospital Sírio-Libanês, que registra mais de 20 milhões de requisições por mês.

O backend integra as TVs dos quartos, o ERP Tasy e a infraestrutura de streaming nas unidades de São Paulo e Brasília. Este artigo descreve as decisões para limitar o custo das requisições, lidar com falhas nas integrações e acompanhar o serviço em produção. A resposta média de 6 ms se refere à API, não ao tempo completo de navegação ou reprodução na TV.

Escala observada em produção

requisições por mês
20M+
resposta média da API
6 ms
taxa de acerto no cache (hit rate)
92%
commits de engenharia no backend
1k+

Visão do sistema

Uma arquitetura com caminhos de degradação claros

Timeouts e limites de retentativa delimitam o tempo gasto nas integrações. O cache combina Redis e memória local para reduzir a dependência de uma única camada durante falhas.

Borda HTTP (Fiber v2)
API Go Core
Cache Híbrido (Redis + sync.Map)
PostgreSQL (pgxpool/sqlc)
Plataformas Externas (TASY / IPTV)
Prometheus & Dashboard
Neste artigo

01 · Contexto

Desafios de um ambiente hospitalar crítico

Em um hospital, qualquer instabilidade na TV do quarto vira um chamado imediato e afeta a experiência do paciente. O backend precisava integrar o ERP hospitalar e o streaming de vídeo mantendo o sistema leve, rápido e extremamente previsível.

  • Integração bidirecional com o ERP TASY (via ESB HSL) para cadastro, ativação e troca de leitos.
  • Orquestração de streaming com geração dinâmica de tokens MD5 com salt para liberação de acesso.
  • Navegação fluida nas Smart TVs Android TV com cache inteligente por endereço MAC.
  • Painel administrativo interno com autenticação segura via cookies JWT HttpOnly e auditoria detalhada.

02 · Arquitetura

Inicialização previsível e limites claros

Optamos pelo Fiber v2 (construído sobre FastHTTP) por sua alta capacidade de processamento e baixo consumo de memória. Toda a configuração da aplicação é definida de forma determinística logo na inicialização, antes de abrir o servidor para receber tráfego.

  • Uso de Fiber v2 e FastHTTP com foco em evitar alocações desnecessárias no heap e reaproveitar buffers.
  • Acesso concorrente ao PostgreSQL via pgx/v5 e pgxpool, usando sqlc para queries tipadas no core e GORM no módulo admin.
  • Timeouts explícitos em todas as pontas: conexões HTTP, consultas ao banco e chamadas para serviços externos.
  • Checagens de prontidão (readiness probes) que validam banco e cache antes de liberar a instância para o tráfego.
Rejeitar requisições de forma rápida sob sobrecarga extrema é muito melhor do que acumular goroutines até estourar a memória do container.

03 · Performance

Menos trabalho na rota principal

A rota que entrega o catálogo e os dados do leito concentra o esforço de otimização. Reduzimos alocações de memória, reutilizamos conexões e acompanhamos a latência para avaliar o resultado.

  • Cliente HTTP customizado (FastHTTP) com pool de conexões por host e limite de 3 tentativas com retentativa inteligente.
  • Processamento de JSON com Sonic JSON e consultas tipadas geradas pelo sqlc, reduzindo trabalho repetitivo no caminho da requisição.
  • Compressão seletiva e cabeçalhos ETag para economizar banda na rede interna do hospital.
  • Dashboard de monitoramento e páginas de administração embarcados diretamente no binário compilado do Go via embed.FS.

04 · Cache

Cache híbrido em duas camadas (Redis + sync.Map)

O Redis é a camada principal de cache. Para lidar com indisponibilidade ou respostas lentas, a aplicação também utiliza memória local, com regras de expiração e limpeza.

  • Redis v8 como camada principal, com tempos de expiração (TTL) definidos pela volatilidade de cada dado (ex: 4 min para sessão da TV).
  • Fallback automático para sync.Map local com rotina de limpeza (janitor) quando o Redis falha ou demora mais de 500ms.
  • Processo em segundo plano (goroutine) para limpeza preventiva diária no horário de menor movimento (entre 03h e 04h).
  • Métricas em tempo real acompanhando acertos (hits), erros e latência separados por camada (Redis vs Memória local).
O fallback reduz a dependência do Redis, mas a memória pertence a cada instância. A validade dos dados e a capacidade dessa camada também precisam entrar na análise de falhas.

05 · Observabilidade

Métricas que ajudam a tomar decisões

Toda a telemetria é exportada nativamente para o Prometheus e exibida em tempo real em um painel interno servido pelo próprio binário em Go.

  • Histogramas de latência (http_request_duration_seconds) de 0.5ms a 30s com rotas normalizadas.
  • Métricas específicas para tempo de consulta no banco (db_query_duration_seconds) e chamadas para APIs externas.
  • Acompanhamento de CPU, memória heap/stack, quantidade de goroutines e pausas do coletor de lixo.
  • Painel web responsivo em /pkg/dashboard embutido via embed.FS, sem depender de ferramentas de terceiros.
Normalizar os parâmetros das URLs no middleware foi fundamental para evitar o estouro de métricas (cardinalidade) no Prometheus.

06 · Segurança

Controle de acesso por papéis (RBAC) e auditoria

O controle de acesso fica nos middlewares JWTMiddleware e AuthorizeMiddleware. Os papéis delimitam as ações permitidas, e os registros de auditoria ajudam a investigar alterações.

  • Sessões administrativas protegidas por cookies HTTP-only, Secure e SameSite, assinadas com JWT (golang-jwt/jwt/v5).
  • Hierarquia de permissões em 4 níveis (Dev, Suporte, Gestor, Analista) com travas no código para impedir elevação indevida de privilégios.
  • Histórico detalhado de auditoria (activity_log) no PostgreSQL registrando quem fez a alteração, o tipo de ação e o valor antigo/novo.
  • Senhas armazenadas como hashes bcrypt (golang.org/x/crypto/bcrypt), com políticas de rotação de chaves para os demais segredos.

07 · Incidentes

Aprendizados práticos tirados da produção

Cada ajuste na arquitetura foi fruto de observação e aprendizado prático durante a operação em ambiente hospitalar.

  • Estouro de métricas no Prometheus → Solução: middleware com padronização rígida do formato das URLs.
  • Pequenas quedas de conexão com o Redis → Solução: cache híbrido transparente com fallback automático para memória local.
  • Tentativas excessivas de conexão com APIs externas → Solução: cliente HTTP otimizado com limite de retentativas e tempo de espera gradual.
  • Inconsistências ao trocar o aparelho de TV → Solução: verificação prévia do MAC address antes de salvar no banco.

08 · Checklist

O que verificar antes de um novo deploy

Antes de publicar, revisamos os limites operacionais, simulamos falhas e verificamos o comportamento sob carga. A média de latência, sozinha, não descreve todos os cenários do serviço.

  • Limites dos pools de conexão (banco e Redis) ajustados de acordo com os núcleos de CPU alocados no container.
  • Teste do mecanismo de fallback do cache simulando a indisponibilidade total do Redis.
  • Verificação das métricas do Prometheus para garantir que não há parâmetros dinâmicos vazando nas rotas.
  • Compilação Docker multi-estágio otimizada (-ldflags='-s -w') e testes de carga executados antes da publicação.

Arquitetura precisa funcionar fora do diagrama

A arquitetura fica mais clara quando decisões e resultados aparecem juntos.

Continue pelos estudos de caso para ver como esses mesmos critérios aparecem em outros contextos de produção.

Explorar projetosRoberto Moraes · Engenheiro de Software