Microservicios vs Monolito: ¿Cuál es el camino correcto?
Si estás leyendo este post puede ser por muchos motivos. Pero probablemente es que estés buscando cómo montar la arquitectura de tu aplicación.
Pues bien, en mi trayectoria profesional he podido sufrir (sí, sí, sufrir) ambas arquitecturas y como es normal las dos tienen ventajas e inconvenientes a la hora de montar una API / aplicación.
Monolito
Un monolito bien organizado, con una buena cobertura de tests y documentación es una buena solución, pero si no tenemos estas dos características y la base de código crece mucho, todo empezará a complicarse. Será cada vez más complicado integrar nuevas funcionalidades y podemos llegar a tener un código espagueti muy interesante. Además esto hará que sea una aplicación más pesada, el despliegue será cada vez más y más lento y consumirá más recursos, sobre todo memoria RAM.
En principio, el hecho de que sea un monolito permite que haya mucha comunicación entre puntos muy diferentes de la aplicación de forma sencilla porque, con una buena arquitectura interna, puede ser una simple llamada a una función, crear una instancia de una clase... Es decir, no necesitamos preocuparnos en cómo se comunica con el exterior como ocurre con microservicios.
✅ Ventajas
- Repositorio único: todo está centralizado en el mismo sitio.
- Desarrollo y mantenimiento: al estar todo centralizado, al principio, el desarrollo es más sencillo y más fácil puesto que cada vez podemos reutilizar más código.
- Flujo de datos más fácil de seguir: dado que todo el código está en el mismo repositorio, seguir el flujo de una petición REST es mucho más sencillo. Hay un punto de entrada y desde ahí es sólo seguir el código.
- Tests: se pueden crear y ejecutar sin hacer muchas piruetas puesto que tenemos todo el código disponible.
❌ Desventajas
- Desarrollo y mantenimiento: sé que lo he puesto en las ventajas. ¿Entonces por qué lo pongo en desventajas?. Es sencillo, en el mundo ideal el código del monolito estará con un 100% de documentación y un 100% de cobertura de test. Exacto en un mundo ideal. Esto casi nunca ocurre, más bien lo contrario. Al aumentar la cantidad de código, disminuye la cantidad de cobertura y de documentación y esto hace que sea más difícil desarrollar y mantener la aplicación.
- Escalabilidad: mayor consumo de recursos, disminuye la posibilidad de escalar la aplicación, al menos sin aumentar los costes.
- Único punto de fallo: aunque la aplicación esté replicada (es decir, ejecutando varias instancias de la aplicación a la vez) si esta se cae dejará de dar servicio por completo y todas las funcionalidades dejarán de estar disponibles.
Microservicios
La realidad es que están de moda. Parece que sólo tienen ventajas respecto a un monolito. Esto no es cierto. Los microservicios implican muchas más incógnitas que un monolito.
La primera: ¿cómo dividimos nuestra aplicación en pedazos?
La segunda: ¿Cómo de pequeños tienen que ser los microservicios?
Y así, podríamos seguir: ¿cómo comunicamos los microservicios entre ellos? ¿HTTP? ¿TCP? ¿Sistema de colas?
Antes en un monolito teníamos todo nuestro código a golpe de llamada a una función o a una clase, ahora está en otro proceso totalmente independiente esto dificulta poder reutilizar parte del código.
✅ Ventajas
- Escalabilidad: al ser una aplicación dividida en pedazos más pequeños podremos escalar aquellas partes de la aplicación que tengamos que redimensionar de forma mucho más sencilla y enfocada a resolver un problema concreto de rendimiento.
- Flexibilidad: si no cambiamos los parámetros de entrada / salida de una funcionalidad, podremos mejorar / cambiar cada componente independientemente.
- División por equipos: cada equipo podría encargarse de una o varias funcionalidades. Simplemente, tendrán que mantener una buena comunicación para mantener compatibles las interfaces entre los distintos microservicios.
- Mayor mantenibilidad: menor cantidad de código por microservicio, significa que la base de código es más fácil de mantener.
❌ Desventajas
- Complejidad: al separar las aplicaciones en procesos independientes la complejidad del sistema aumenta, es necesaria una gestión más rigurosa y una planificación cuidadosa.
- Depuración: encontrar el error en un punto del flujo de los datos es mucho más difícil. Hay que bucear entre los microservicios para encontrar el fallo.
- Mayor latencia: al ir propagando una petición entre los distintos microservicios, la latencia de cada una de ellas aumenta. Además hay que desarrollar mecanismos (como circuit-breaker) para evitar una cascada de errores en el sistema.
- Coste: por muy bien optimizados que estén los microservicios en cuanto a consumo de CPU y RAM, serán muchos más que un monolito y por ello, en conjunto, consumirán más recursos.
Conclusión
Ambas arquitecturas son buenas elecciones, la dificultad radica en cuál de las dos utilizar para el problema a resolver.
Mi opinión y mi experiencia me dicen que un sistema dividido y bien organizado (ya sean micro o mini servicios) es más extensible, más modular, más mantenible y además escala mucho mejor que un monolito.
Espero que te haya gustado este post. Te invito a que me cuentes en los comentarios otras ventajas y desventajas de ambas arquitecturas para que entre todos aprendamos otros puntos de vista. Porque como en todos los posts de BKND, todo es una opinión en base a una experiencia. No es una fuente de verdad absoluta, ni mucho menos. Simplemente, son experiencias y opiniones que quiero compartir contigo. Espero que así lo percibas y que te sirva de ayuda.