Durante los últimos años, la palabra "microservicios" se escucha mucho cuando hablamos de arquitecturas de datos. Por un tiempo, parecía que si no estabas utilizando esta arquitectura, te estabas quedando en el pasado. Sin embargo, en la práctica, en ixpantia hemos visto que esta arquitectura no es necesariamente la mejor opción para todas las soluciones de datos. Hoy, queremos hablar de una alternativa que a lo interno de ixpantia ha tomado fuerza: el Monolito Modular. ¿Qué es, cómo se diferencia del monolito "de siempre" y cuándo deberían elegirlo por encima de los microservicios?
La filosofía detrás de los microservicios es contundente y elegante: "haz una cosa, y hazlo bien". Se trata de construir servicios con una sola función, desarrollados en una cultura de despliegue continuo (CI), que son independientes, stateless (sin estado propio) y que se comunican entre sí a través de llamadas a APIs.
Sin embargo, hay una trampa en la que es muy fácil caer cuando se utilizan microservicios: le llamamos Monolito Distribuido. Este es un anti-patrón de los microservicios, dicho de otra forma, una mala práctica a la que muchos caen cuando construyen una arquitectura de este tipo. Ocurre cuando creas una solución que aparenta ser distribuida, pero en realidad sus componentes están altamente acoplados y son dependientes entre sí. Lo notas cuando dos o más servicios comparten una misma base de datos, por ejemplo. En esos casos, no hay garantía de consistencia de datos.
Por otro lado, cuando la lógica de negocio no está bien distribuida, tu proceso se vuelve un largo hilo de microservicio 1, que llama a microservicio 2 y que luego este llama a microservicio 3 y así sucesivamente de manera síncrona, sin utilizar herramientas como colas o jobs. En estos casos hay demasiada comunicación síncrona entre ellos. También puede suceder cuando la lógica de negocio está distribuida sin límites claros, entonces entre microservicios no es posible hacer una clara trazabilidad. Al final, tienes toda la complejidad de los microservicios, pero sin ninguna de sus ventajas.
Si, hay que empezar aclarando que el monolito clásico era un plato de espagueti, todo el código de una solución en un solo plato, sin límites claros y con un proceso de cambio sumamente ralentizado. Sin embargo, el Monolito Modular aplica los aprendizajes de la arquitectura de microservicios, pero dentro de una sola “unidad”.
Gracias a la evolución tecnológica —como los lenguajes full-stack (JS/TS, Rust), el soporte asíncrono real que se estandarizó en los últimos años (Python en 2016, JS en 2017, Rust en 2019) y los sistemas de tipado de datos modulares (que actúan como contratos o interfaces). Hoy podemos construir de una forma mucho más inteligente.
Un monolito modular comparte la misma cultura de automatización y validación que los microservicios, pero se compone de módulos independientes que se comunican a través de interfaces muy bien definidas. Cada módulo se enfoca en un dominio de negocio específico, opera de forma asíncrona y, al igual que los microservicios, la solución entera es stateless.
Quizás recuerdes este gráfico que data al 2015:
En resumen este gráfico dictaba que los monolitos eran para sistemas simples (baja complejidad) y los microservicios para sistemas complejos, para mantener una buena relación con la productividad de la solución. Hoy en día, con el monolito modular, la realidad es diferente. Veamos cómo se comparan:
Ventajas del monolito modular:
Ventajas de los microservicios:
Los microservicios sufren de un mantenimiento de infraestructura mucho más complejo y un peor rendimiento debido a la latencia de la red. Por su parte, el monolito modular te amarra a no tener mucha diversidad de lenguajes y requiere estrategias como feature flags ya que todos los componentes se versionan juntos.
Un ejemplo de esta transición es el caso del equipo de Análisis de Calidad de Video (VQA) de Amazon Prime Video. Inicialmente, diseñaron su herramienta para monitorear audio y video utilizando una arquitectura serverless distribuida (AWS Step Functions, AWS Lambda y Amazon S3).
Sin embargo, al intentar escalar para monitorear miles de transmisiones en vivo simultáneas, se topan con serios cuellos de botella:
La solución fue consolidar todos los componentes (conversión de medios, detectores de fallas y orquestación) en una sola aplicación ejecutada en Amazon EC2 y ECS. Al mover los procesos a la memoria de la instancia en lugar de pasarlos por la red a un bucket de S3, redujeron los costos de infraestructura en más de un 90% y mejoraron drásticamente su rendimiento y escala.
Este caso demuestra que, si bien los microservicios funcionan a escala en ciertos escenarios, un monolito modular puede ser más eficiente en costo y rendimiento cuando existe un intercambio intenso de datos entre componentes.
No asuman que su próximo proyecto necesita microservicios por defecto. Si no tienen múltiples equipos trabajando en lenguajes distintos que requieran despliegues y escalaciones totalmente independientes, un Monolito Modular probablemente te dará un mejor rendimiento, menores costos de infraestructura y menos dolores de cabeza operativos.
En ixpantia, construimos arquitecturas que se adaptan a la realidad y escala de nuestros clientes, y muchas veces, la simplicidad modular de un monolito modular es exactamente la herramienta correcta para el trabajo.