Monolito modular, microservicios y evolución | Nicolás Garzón
Monolito y microservicios no representan inmadurez frente a madurez. Son topologías con costos distintos. La decisión correcta depende de límites del dominio, equipos, datos, escala y capacidad operativa.
La pregunta no es “¿cuándo debo dejar el monolito?”, sino:
¿Qué necesita cambiar o desplegarse de forma independiente?
¿Qué datos e invariantes deben permanecer juntos?
¿Qué equipo posee cada capacidad?
¿Qué costo operativo puede sostenerse?
Texto
Copiar monolito modular
→ autonomía lógica dentro de una unidad de despliegue
microservicios
→ autonomía lógica + despliegue y operación independientesUna sola unidad de despliegue. Puede estar bien estructurada o ser una masa acoplada.
Desarrollo local directo.
Debugging y trazas sencillos.
Transacciones locales.
Menor infraestructura.
Refactors coordinados baratos.
Despliegue global.
Escalado conjunto.
Fallo de proceso con impacto amplio.
Ownership difuso si no existen módulos.
El problema no es “ser monolito”, sino perder límites y permitir dependencias arbitrarias.
Organiza una aplicación por capacidades con API pública y ownership.
Texto
Copiar application
├── catalog
├── inventory
├── orders
├── payments
└── delivery
Imports solo mediante API pública.
Datos con propietario.
Prohibición de escrituras cruzadas.
Contratos internos explícitos.
Pruebas de arquitectura.
Métricas por módulo.
Esto crea seams para extraer sin pagar todavía el costo de red.
Un servicio necesita más que un proceso separado.
Capacidad de desplegar y revertir sin coordinar todo.
Ownership de datos.
Contrato compatible.
SLO, observabilidad y on-call.
Capacidad de operar ante fallos ajenos.
Equipo responsable.
Si comparte base, despliegue y ciclo de cambios, probablemente es un monolito distribuido.
Timeouts, latencia, resultados desconocidos y fallos parciales.
Transacciones locales reemplazadas por reservas, eventos, sagas o consistencia eventual.
Versionado, deprecación y consumer compatibility.
Pipelines, secretos, certificados, discovery, métricas, trazas y logs por servicio.
Más ownership y comunicación formal. Sin equipos independientes, la fragmentación puede reducir velocidad.
Despliegues coordinados.
Llamadas síncronas encadenadas.
Base compartida.
Librería de dominio común.
Un cambio toca varios repositorios.
Ningún servicio puede operar si otro falla.
Conserva la complejidad de distribución sin obtener autonomía.
La capacidad posee lenguaje, datos e invariantes reconocibles.
Un equipo necesita controlar roadmap y despliegue.
Procesamiento o almacenamiento crece de forma independiente.
Requisitos de seguridad, regulación o fallo justifican separación.
Una capacidad cambia y se publica mucho más que el resto.
Lead time, incidentes o saturación muestran que la unidad actual es un límite.
No son señales suficientes: cantidad de clases, moda o “algún día tendremos millones de usuarios”.
Define API, ownership y dependencias dentro del monolito.
Mide tráfico, cambios, errores, datos y consumidores.
Separa semántica interna de la interfaz futura.
Establece fuente de verdad, backfill, sincronización y reconciliación.
Strangler, branch by abstraction o feature flag.
Shadow traffic, canary y métricas.
El nuevo servicio se vuelve autoridad.
Elimina camino, datos y sincronizaciones anteriores.
Notificaciones suele ser candidata porque:
Puede procesarse asíncronamente.
Tolera consistencia eventual.
Escala por volumen de mensajes.
El fallo no debe bloquear pedidos.
Texto
Copiar Orders confirma
→ outbox publica OrderConfirmed
→ Notifications consume
→ envía email/SMS
→ registra entrega
Duplicados.
DLQ.
Templates versionados.
Proveedor lento.
Reintentos.
La extracción sigue necesitando idempotencia y observabilidad.
Inventario y ventas pueden necesitar transacciones locales, dominio todavía cambiante y equipo único. Extraerlo introduce timeouts y coordinación antes de tener límites estables.
Una alternativa es mantener módulo fuerte, medir carga y conservar contrato interno.
Un monolito puede escalar horizontalmente si es stateless y utiliza recursos compartidos adecuadamente. Microservicios permiten escalar partes, pero cada servicio también puede tener cuellos en base o proveedores.
No uses topología como sustituto de profiling.
Separar procesos puede contener fallos, pero también crea nuevas dependencias.
Texto
Copiar monolito:
fallo del proceso puede afectar todo
microservicios:
fallo parcial puede propagarse por cadenasSe necesitan timeouts, bulkheads, degradación y contratos.
Más servicios amplían identidades, secretos, red y superficie. También pueden mejorar aislamiento. El beneficio depende de controles, no del número de procesos.
Unitarias y módulo-integración.
Pruebas de límites.
E2E simples.
Contract tests.
Integración por servicio.
Pruebas de fallos y compatibilidad.
E2E selectivos.
Una arquitectura evolutiva conserva opciones y usa feedback:
Texto
Copiar driver
→ modularidad suficiente
→ fitness functions
→ observación
→ migración incrementalNo significa cambiar constantemente. Significa que las decisiones tienen mecanismos de adaptación.
Un servicio separado puede justificarse por aislamiento aunque no exista autonomía organizacional.
Una capacidad puede necesitar deployment dedicado sin convertir todo el sistema en microservicios.
Durante migración puede existir, pero debe tener plan, permisos y fecha de retiro.
Un servicio por entidad aumenta red y coordinación. El límite debe representar capacidad.
Un servicio por tabla.
Compartir escritura.
Extraer antes de modularizar.
Cadenas síncronas largas.
Brokers sin capacidad operativa.
No retirar el código legado.
Medir éxito por cantidad de servicios.
Ignorar costos humanos.
Monolito modular y microservicios son opciones, no etapas.
Autonomía exige datos, despliegue, operación y equipo.
Distribuir introduce fallos parciales y consistencia eventual.
Modularizar primero reduce riesgo de extracción.
La decisión debe basarse en dolor y evidencia.
Arquitectura evolutiva usa seams, métricas y migraciones incrementales.
¿Qué diferencia un monolito modular de uno accidental?
¿Qué señales justificarían extraer Inventario?
¿Por qué una base compartida debilita autonomía?
¿Qué pasos requiere transferir ownership de datos?
¿Cómo puede un monolito escalar sin dividirse?
Arquitectura orientada a eventos profundiza en una forma de colaboración asíncrona útil entre módulos y servicios.