Refactorización de un monolito (Refactoring of a monolith)
Tags: architecture, cleancode
Published: 2021-12-08 00:05:12

Lo primero a tener en cuenta es que el título del artículo no sugiere directamente comenzar a migrar un proyecto de una arquitectura monolítica a una de microservicios. Previamente, deben tenerse en cuenta algunos puntos importantes.

- La arquitectura monolítica no es un anti-patrón de diseño.
- La arquitectura de microservicios no es la solución a todos nuestros problemas. Adoptar este tipo de arquitectura no solucionará problemas como código de mala calidad, falta de testing, baja calidad en el proceso de desarrollo.
- Éxito != Cantidad de microservicios

___

**Arquitectura monolítica**
Es una estructura que consta de un gran sistema en el que se integran la gran mayoría de las funcionalidades y componentes de un proyecto. Son aplicaciones basadas en un lenguaje de programación específico, al igual que poseen una sola base de datos.

_Algunas ventajas:_

- Simplicidad: fáciles de construir, testear y deployar.
- Asuntos interdisciplinarios: al ser un "único" código, pueden manejarse de una mejor manera estos asuntos interdisciplinarios (cross-cutting concerns), como el logging, manejo de configuraciones, monitoreo de performance.
- Performance: Normalmente los componentes en un monolito comparten memoria, lo que hace que las comunicaciones entre los diferentes servicios sean más rápidas.

_Algunas desventajas:_

- Confiabilidad: un simple error en cualquiera de los módulos/componentes puede comprometer y dejar fuera de servicio a toda la aplicación.
- Actualizaciones: debido a que es un gran bloque de código una actualización requiere deployar toda la aplicación nuevamente.
- Stack de tecnologías: un monolito usa el mismo stack de tecnologías. Realizar un cambio del mismo es muy costoso, tanto en tiempo como en costos involucrados.

**Arquitectura de microservicios**
Por otro lado, consisten en servicios independientes y poco acoplados entre sí. De hecho, esta arquitectura divide los componentes de nuestra aplicación en pequeños y autónomos servicios que pueden ser deployados y escalados independientemente. A diferencia de los monolitos, estos microservicios pueden estar programados en diferentes lenguajes de programación, al igual que poseer varias bases de datos.

_Algunas ventajas:_

- Escalabilidad: para escalar una aplicación de microservicios solamente se necesitan escalar ciertos componentes, lo que optimiza el uso de recursos.
- Bajo nivel de acoplamiento: los microservicios están poco acoplados entre sí, por ende no son interdependientes y pueden ser testeados individualmente. Además, hace a la aplicación más adaptable a los cambios a lo largo del tiempo.

_Algunas desventajas:_

- Equipo humano preparado: los beneficios de los microservicios son discutibles si no se tiene un equipo preparado.
- Testeo y monitoreo: Una vez que dividimos a la aplicación en componentes, tendremos un montón de partes individuales sobre las que realizar seguimiento y eventualmente fixes. Sin unas buenas herramientas de testeo y monitoreo, las cosas pueden salirse de control muy rápido.
- Velocidad de comunicación: al ser servicios aislados la comunicación es más complicada. O bien, usan HTTP o directamente queues.

___

**Cómo decidir**
Generalmente, las arquitecturas monolíticas son la opción correcta para aplicaciones simples y pequeñas.

Por otro lado, una arquitectura de microservicios es una buena opción cuando queremos desarrollar sistemas más complejos, especialmente cuando se tiene un equipo de trabajo capacitado para este tipo de aplicaciones.

Entonces, cuando tenemos que elegir entre una y otra arquitectura, debemos considerar estos cuatro puntos básicos:
- ¿Tenemos un equipo capacitado y que puede trabajar con microservicios?
- ¿Tenemos la infraestructura suficiente para trabajar con aplicaciones distribuidas?
- ¿Hemos evaluado los riesgos de negocio involucrados?
- ¿Están definidos claramente los límites de nuestra aplicación?

Si se decide adoptar una estructura de microservicios, deben tenerse en cuenta beneficios y costos al momento de elegir por cual servicio comenzar.

___

**Relación costo-beneficio de extracción de un servicio**
 
| Beneficios                        | Costos                        |
| -----------                       | -----------                   |
| Resuelve un problema significativo| Adaptar / Reescribir el módulo|
| Frecuencia de uso del servicio    | Dificultad en desacoplar dependencias|
| Escalabilidad del servicio        | Nivel de participación del servicio en [sagas](https://https://docs.microsoft.com/en-us/azure/architecture/reference-architectures/saga/saga)|

Características de cada (micro)servicio:
- Altamente mantenible y testeable.
- Puede ser deployado independientemente.
- Bajo responsabilidad de un pequeño equipo.
- Organizado en torno a las capacidades del negocio.

___

Pasos recomendados para migrar de una arquitectura monolítica a una de microservicios

1. Identificar los componentes de nuestra aplicación / proyecto.
2. Refactorizar los componentes.
3. Identificar las dependencias de los componentes.
4. Identificar los diferentes grupos de componentes.
5. Crear una API para utilizarla como el único modo de comunicación entre el sistema, sus componentes y los usuarios del sistema.
6. Migrar los grupos de componentes a macroservicios.
7. Migrar de macroservicios a microservicios.
8. Repetir los pasos 6 y 7.

___

_Fuentes:_
- https://searchapparchitecture.techtarget.com/tip/Pros-and-cons-of-monolithic-vs-microservices-architecture
- https://insights.sei.cmu.edu/blog/8-steps-for-migrating-existing-applications-to-microservices/
- https://chrisrichardson.net/post/refactoring/2020/08/21/ten-principles-for-refactoring-to-microservices.html