Saltar al contenido principal
Volver a insights

Caso Técnico · Ingeniería Backend

Go en producción: arquitectura, caché y operación

Decisiones de arquitectura, caché y observabilidad en el backend Go de Hospital Sírio-Libanês, que registra más de 20 millones de solicitudes al mes.

El backend conecta las TVs de las habitaciones, el ERP Tasy y la infraestructura de streaming en São Paulo y Brasília. Este artículo describe decisiones para limitar el costo de las solicitudes, tratar fallos en las integraciones y observar el servicio en producción. La respuesta media de 6 ms corresponde a la API, no a toda la experiencia de navegación o reproducción en la TV.

Escala observada en producción

peticiones por mes
20M+
respuesta media de la API
6 ms
tasa de acierto de caché sostenida
92%
commits de ingeniería backend
1k+

Visión del sistema

Una arquitectura con degradación controlada

Los timeouts y los límites de reintentos acotan el tiempo dedicado a las integraciones. La caché combina Redis y memoria local para reducir la dependencia de una sola capa durante fallos.

Borde HTTP (Fiber v2)
API Go Core
Caché Híbrida (Redis + sync.Map)
PostgreSQL (pgxpool/sqlc)
Plataformas Externas (TASY / IPTV)
Prometheus & Dashboard
En este artículo

01 · Contexto

Desafíos reales del ecosistema hospitalario

La inestabilidad en la TV de la habitación genera trabajo de soporte y afecta la experiencia del paciente. El backend debía integrar Tasy y el streaming IPTV con un uso de recursos y un comportamiento ante fallos previsibles.

  • Integración bidireccional con ERP TASY vía ESB HSL para activación, inactivación y cambio de habitaciones.
  • Orquestación del middleware IPTV con generación dinámica de tokens MD5 con salt.
  • Navegación continua en Smart TVs Android TV respaldada por caché agresiva por dirección MAC.
  • Panel administrativo interno protegido por cookies HTTP-only JWT con auditoría completa.

02 · Arquitectura

Bootstrap predecible y límites estrictos

Elegimos Fiber v2 y FastHTTP con foco en el rendimiento y el uso de memoria. La configuración de la aplicación se establece al iniciar, antes de aceptar tráfico.

  • Fiber v2 y FastHTTP con reutilización de buffers para reducir asignaciones innecesarias.
  • Acceso a PostgreSQL de alta concurrencia vía pgx/v5 y pgxpool, usando sqlc para consultas type-safe y GORM en admin.
  • Timeouts explícitos en todas las capas (HTTP Read/Write, vida útil de conexiones DB y timeouts de dial).
  • Readiness probes verificando la salud de PostgreSQL y Redis antes de enviar tráfico a las nuevas instancias.
Rechazar solicitudes rápidamente bajo sobrecarga limita la acumulación de goroutines y ayuda a controlar el uso de memoria del contenedor.

03 · Rendimiento

Menos trabajo en la ruta principal

La ruta que entrega el catálogo y los datos de la habitación concentra el esfuerzo de optimización. Redujimos asignaciones de memoria, reutilizamos conexiones y seguimos la latencia para evaluar el resultado.

  • Cliente HTTP de alto rendimiento (FastHTTP) encapsulado con pools por host y límite de 3 reintentos.
  • Procesamiento de JSON con Sonic JSON y consultas tipadas generadas por sqlc, reduciendo trabajo repetitivo en la ruta de la solicitud.
  • Soporte para compresión selectiva y cabeceras ETag para ahorrar ancho de banda en la red hospitalaria.
  • Dashboard de monitoreo y plantillas HTML integrados directamente en el binario Go mediante embed.FS.

04 · Caché

Caché híbrida en dos capas (Redis + sync.Map)

Redis es la capa principal de caché. Para tratar caídas o respuestas lentas, la aplicación también utiliza memoria local, con reglas de expiración y limpieza.

  • Capa primaria en Redis (v8) con TTLs ajustados por volatilidad (ej. 4 min para caché de login MAC).
  • Fallback automático a sync.Map local con rutina janitor de TTL cuando Redis falla o supera los 500ms.
  • Goroutine dedicada en background para limpieza preventiva diaria entre las 03:00 y 04:00 AM.
  • Métricas en tiempo real de aciertos, fallos y errores segregadas por capa (Redis vs Local).
El fallback reduce la dependencia de Redis, pero la memoria pertenece a cada instancia. La validez de los datos y la capacidad de esta capa también deben considerarse al evaluar fallos.

05 · Observabilidad

Métricas normalizadas y Dashboard integrado

Telemetría completa exportada nativamente para Prometheus y visualizada en un panel de control en tiempo real servido por el propio binario Go.

  • Histogramas http_request_duration_seconds con buckets personalizados (0.5ms a 30s) y rutas normalizadas.
  • Métricas dedicadas de base de datos (db_query_duration_seconds) e integraciones externas (ESB/IPTV).
  • Métricas de infraestructura en tiempo real: uso de CPU, memoria heap/stack, goroutines y conexiones de pool.
  • Dashboard web responsivo servido en /pkg/dashboard integrado mediante embed.FS sin dependencias externas.
La normalización obligatoria de parámetros de ruta en middleware evitó la explosión de cardinalidad en Prometheus.

06 · Seguridad

Control de acceso por roles y registros de auditoría

JWTMiddleware y AuthorizeMiddleware aplican el control de acceso. Los roles definen las acciones permitidas y los registros de auditoría ayudan a investigar cambios.

  • Cookies de sesión admin_token protegidas con HttpOnly, Secure, SameSite y firmadas con golang-jwt/jwt/v5.
  • Matriz RBAC en 4 niveles (Dev, Soporte, Gestor, Analista) con restricciones técnicas para impedir elevación de privilegios.
  • Historial de auditoría (activity_log) en PostgreSQL registrando colaborador, acción (CREATE/UPDATE/DELETE), entidad y deltas.
  • Contraseñas almacenadas como hashes bcrypt (golang.org/x/crypto/bcrypt), con políticas de rotación de claves para los demás secretos.

07 · Incidentes

Lecciones prácticas extraídas de producción

Los incidentes en producción orientaron cambios en los límites de solicitudes, la caché y la instrumentación. Estos son los problemas y las respuestas que dieron forma al servicio.

  • Explosión de cardinalidad en Prometheus → Solución: middleware de normalización estricta de endpoints.
  • Caídas de red en Redis → Solución: caché híbrida transparente con fallback automático a sync.Map local.
  • Reintentos desordenados en el ESB → Solución: cliente FastHTTP encapsulado con backoff exponencial y límite finito.
  • Inconsistencias al cambiar una TV → respuesta: verificar la dirección MAC antes de guardar el dispositivo en la base de datos.

08 · Lista de Verificación

Qué validar antes del próximo despliegue

Antes de publicar, revisamos los límites operativos, simulamos fallos y verificamos el comportamiento bajo carga. La latencia media, por sí sola, no describe todos los escenarios del servicio.

  • Límites de pgxpool y conexiones Redis ajustados al número de núcleos CPU disponibles en el contenedor.
  • Mecanismo de fallback de caché verificado mediante inyección de fallos (caída de Redis simulada).
  • Métricas de Prometheus auditadas con rutas normalizadas y sin fuga de IDs dinámicos en labels.
  • Compilación Docker multi-stage optimizada con -ldflags='-s -w' y pruebas de carga previa al lanzamiento.

La arquitectura debe funcionar fuera del diagrama

La arquitectura se vuelve más clara cuando decisiones y resultados aparecen juntos.

Continúa por los casos de estudio para ver cómo estos mismos criterios aparecen en otros contextos de producción.

Explorar proyectosRoberto Moraes · Ingeniero de Software