Arquitectura monolítica frente a microservicios: elección de la arquitectura adecuada para el proyecto

Hay dos formas de construir sistemas complejos, ya sea usando arquitectura monolítica o de microservicios. ¿Cuál elegir y cuándo? ¡Vamos a resolverlo!

Seleccionar y construir la arquitectura adecuada es la tarea número uno en una lista de tareas para el desarrollo de productos de software. Hoy en día, existe una opinión común de que la arquitectura monolítica es algo obsoleto, mientras que los microservicios son una tecnología de vanguardia. Sin embargo, esto no es cierto. Ambos tipos de arquitectura se pueden usar de manera segura para diferentes propósitos, la única pregunta es: ¿cómo elegir el correcto para un caso particular? Echemos un vistazo más de cerca para encontrar la respuesta.

Imaginemos que estamos construyendo una aplicación compleja usando arquitectura monolítica. Esto es lo que parece: todos los componentes existen como una sola pieza de código, cada uno compartiendo una única base de datos con el resto.

Al principio, todo es genial. La aplicación es fácil de construir, implementar y probar como un código monolítico.

Sin embargo, los productos exitosos ahora viven años y años, creciendo constantemente en tamaño y complejidad. Si está planeando una vida larga y feliz para su aplicación (y definitivamente lo es), eventualmente, puede terminar teniendo un infierno monolítico en lugar de una aplicación hermosa y fácil de administrar.

¿Por qué es así?

Las aplicaciones con arquitectura monolítica son un conjunto de módulos estrechamente acoplados que son difíciles de distinguir de un fragmento de código monolítico. Por eso es bastante difícil:

  • Actualice y amplíe módulos separados: deberá volver a implementar la aplicación completa cada vez que necesite actualizar un solo módulo.
  • Retroceda cuando algo salga mal; nuevamente, deberá volver a implementar toda la aplicación para deshacer los cambios en un módulo.
  • Pruebe unidades de código separadas: un monolito es realmente difícil de dividir en módulos separados.
  • Realice revisiones de código: las piezas de código suelen ser muy grandes y, por lo tanto, difíciles de revisar.
  • Administre un gran equipo de desarrolladores: un día, es posible que no pueda determinar quién es responsable de qué código.
  • Escale la aplicación horizontalmente, en otras palabras, agregue máquinas más económicas para escalar módulos de alta carga de la aplicación. La escala horizontal generalmente se asocia con microservicios; sin embargo, en el caso de aplicaciones monolíticas, difícilmente es una opción. Como las aplicaciones monolíticas no se pueden dividir fácilmente en servicios separados, tendrá que escalar la aplicación completa cada vez que haya un cuello de botella en un módulo.

Los puntos descritos anteriormente son suficientes para comprender la idea principal: la arquitectura monolítica es una mala elección para productos en constante evolución.

¿Quién nos va a salvar entonces? Microservicios!

La descomposición funcional es el núcleo de la arquitectura de microservicios.

Volvamos a nuestro ejemplo anterior. Si implementamos la misma aplicación con el uso de la arquitectura de microservicios, se vería como se muestra en la imagen a continuación. Lo que antes era una sola pieza de código ahora son servicios separados, cada uno con su propia base de datos y un único punto de entrada para todos ellos.

Esta es la descomposición funcional en acción. ¿Cuáles son sus beneficios sin embargo?

Con la arquitectura de microservicios, es mucho más fácil:

  • Trabaje en una determinada funcionalidad y tenga en cuenta su alcance. En el caso de los microservicios, el alcance de la funcionalidad de la aplicación se descompone en las partes más pequeñas posibles (módulos o servicios), que son mucho más fáciles de manejar que las aplicaciones monolíticas gigantes.
  • Administre y revise todos los cambios realizados en el código a medida que se realizan en servicios claramente separados.
  • Pruebe los servicios por separado, ya que cada uno de ellos es responsable de una funcionalidad diferente: puede probar cada uno por separado sin afectar a los demás. Una buena opción para A / B y pruebas de capacidad.
  • Actualice y brinde servicios por separado, así como administre versiones parciales y pruebe las características que ya se han lanzado.
  • Sea flexible con pilas tecnológicas innovadoras: puede elegir una pila tecnológica nueva para cada servicio.
  • Gestionar responsabilidades. Cada equipo es responsable de un servicio en particular y puede desarrollar, probar e implementar el código de forma independiente y autónoma para que nadie tenga que depender del progreso de otras personas. Además, como beneficio adicional, siempre sabes a quién culpar.
  • Escale horizontalmente en lugar de verticalmente, sin involucrar a todo el sistema.

Suena idílico, ¿verdad? Sin embargo, ¿es la arquitectura de microservicios una bala de plata? ¡La respuesta es no!

A continuación se muestra la "verdad fea" sobre microservicios:

  • Los sistemas distribuidos siempre traen un nuevo conjunto de problemas. En el caso de los microservicios, por ejemplo, tenemos muchos servicios independientes que necesitan comunicarse a través de HTTP, o mensajes, o algo más, y esto puede causar muchos problemas, desde problemas de red hasta el desbordamiento del bus de mensajes, cuando los mensajes pueden ser perdido y nunca entregado, en el orden incorrecto de mensajes, etc. Como referencia: con la arquitectura monolítica, la comunicación entre los servicios es simplemente llamar al código dentro del código.
  • Esto es genial porque con los microservicios no tiene que atenerse a una pila de tecnología y siempre puede probar algo nuevo al agregar una nueva función a la aplicación. Le ayuda a mantenerse siempre actualizado. Sin embargo, la otra cara de la moneda es que el uso de nuevas tecnologías debe estar bajo un estricto control. De lo contrario, después de un tiempo, su aplicación se verá como un zoológico donde cada servicio se desarrolla con un nuevo marco o incluso un idioma. Por lo tanto, es mejor tener los lenguajes, marcos y enfoques esenciales estandarizados en todo el sistema y cambiarlos solo cuando sea realmente necesario.
  • Todo el sistema debe estar diseñado para resistir pequeños errores en caso de que no desee que la aplicación se caiga debido a un error en un solo servicio.
  • La parte "poco atractiva" de los microservicios son las transacciones distribuidas. Cuando la aplicación es una sola pieza de código, generalmente tiene una base de datos, y cualquier solicitud puede manejarse a través de una sola transacción de base de datos. Con los microservicios, el sistema se distribuye; esto significa que cada servicio tiene su propia base de datos y la coherencia de los datos debe mantenerse cuidadosamente en todo el sistema.
     De hecho, a veces la necesidad de transacciones distribuidas es solo el resultado de un mal diseño, pero todavía hay casos comerciales reales que requieren un manejo adecuado de las transacciones distribuidas. Existen varios enfoques para el manejo efectivo de transacciones distribuidas, como el abastecimiento de eventos.
  • Con los microservicios, es realmente fácil lanzar, escalar, implementar y probar servicios por separado, pero operar todo el sistema puede ser muy complejo. Los microservicios deben diseñarse con mucho cuidado desde el principio. De lo contrario, después de un tiempo, puede encontrarse en el infierno de los microservicios, donde todos los servicios están conectados entre sí y la falla en un solo servicio conduce a la interrupción completa del sistema. Los contenedores y los sistemas de orquestación de contenedores pueden ser de gran ayuda al administrar microservicios.

Aunque ni la arquitectura monolítica ni la de microservicios son un enfoque infalible, este es el punto principal. A pesar del conjunto de nuevos problemas que nos traen los microservicios, existen soluciones reales para casi todos ellos. En el caso de la arquitectura monolítica, no hay muchas maneras de facilitarle la vida, y solo necesita sufrir en silencio. :)

En general, la mayoría de las aplicaciones en el mundo se vuelven más complejas con el tiempo, y es difícil encontrar una aplicación que siempre funcione perfectamente con un pequeño conjunto de funciones y que no crezca con el tiempo. Sin embargo, tales aplicaciones existen, ¡y para ellos la arquitectura monolítica es perfecta!

Por lo tanto, no existe una solución única para todos. Tanto las arquitecturas monolíticas como las de microservicios tienen todo el derecho de existir: solo tiene que elegir la correcta según sus propósitos.

Publicado originalmente en yellow.id.