Microservicios: que son, cómo funcionan y mejores prácticas de uso

Para partir muchos conocerán el concepto de microservicio, otros simplemente han oído hablar de ellos, pero, ¿qué son?. Los microservicios son componentes de software en su grado más mínimo de funcionalidad posible. Son componentes que pueden tener una funcionalidad aislada y que logran tener un gran desacoplamiento. Esto en contraste con los softwares tradicionales monolíticos que compilan todos los componentes en una sola pieza.

Los microservicios son independientes, es decir, que solo necesitan ser alojados en contenedores con requerimientos mínimos para su ejecución y que pueden interactuar con otros microservicios según sea la necesidad de uso.

¿Por qué o cuándo usar microservicios?

Los microservicios permiten ejecutar funciones por separado y, si es que por algún motivo un servicio falla, el resto seguirá funcionando sin verse afectado por el microservicio que tiene problemas. 

En el caso de aplicaciones monolíticas, , si tenemos un problema con un componente debemos detener la ejecución, corregir y hacer un nuevo deploy de la nueva versión con el fix realizado. ¡Implicaría que tengamos que detener el sistema completo viéndose afectados otros componentes que funcionaban correctamente y que no tienen relación con el componente que falló!

© Kranio 2021
© Kranio 2021
Ahora que sabes que son los microservicios, te preguntarás, cómo lo harán para que cada uno funcione y estos conversen entre sí.

Bueno, para implementar microservicios existen modelos de referencia que podemos seguir. Estos modelos te guían para lograr que al separar un conjunto de funciones en microservicios estos estén perfectamente desacoplados y no exista una dependencia entre ellos.

Modelos de referencia

Para implementar una arquitectura de microservicios debes tener en cuenta los siguientes aspectos:

  • Realizar un análisis previo y definir por qué es necesaria una arquitectura de microservicios.
  • Definir qué modelo de referencia es el adecuado para resolver la necesidad (arquitecturas de referencia).
  • Un modelo de implementación con el que puedas concretar la implementación de los componentes del modelo de referencia. Por ejemplo, si usas Java y Spring, debes contar con todos los componentes de este framework,  necesarios que soporten esta arquitectura.
  • Un modelo de despliegue que te permita definir cómo se van a desplegar los componentes de la arquitectura. Por ejemplo, si usas contenedores, Docker y lo necesario para utilizar las aplicaciones de estos contenedores.

Dado lo anterior, para contar con un buen modelo de arquitectura de microservicios, al menos debes considerar los siguientes componentes y conceptos necesarios:

  • Servidor de configuración central (repositorio de fuentes centralizado, versionamiento y ciclo de vida del software).
  • Servicio de registro/discovery (registro de microservicios, disposición de endpoints).
  • Balanceo de carga (orquestador de servicios).
  • Tolerancia a fallos (trabajo en solucionar fallos de manera aislada sin afectar el resto de llamadas).
  • Exposición de servicios (Gateway).
  • Componente de autorización (implementación de una capa de seguridad).
  • Monitoreo (herramientas que permitan monitorear salud de pods, carga de trabajo, fallos).

Ya que tienes considerado estos componentes, es el momento de pensar cómo estructuramos cada microservicio. Para comenzar debes tener un análisis previo relacionado al dominio de negocio para modelar los microservicios.  Conocer y manejar el dominio de la empresa, los objetivos y los requisitos es uno de los grandes desafíos, dado que no hay un proceso mecánico que nos guie a un diseño perfecto. Pero lo que sí puedes hacer, es seguir arquitecturas que separan por capas y aíslan el dominio de una manera que los demás componentes se comunican entre ellos, sin verse afectados ni mezclados.

Arquitectura Hexagonal

La arquitectura Hexagonal es un patrón de diseño de software, que busca desacoplar la aplicación por componentes. Estos componentes forman una serie de capas que serán fácilmente conectables entre sí mediante puertos y adaptadores. Un puerto es la definición de una interfaz pública y un adaptador es una especialización de un puerto para un contexto concreto. Así los componentes pueden llegar a ser intercambiables en cualquier nivel o capa. Además podemos aislar los test automatizados sin necesidad de pasar por varias capas para hacer pruebas a una funcionalidad específica.

Esta Arquitectura se representa por una forma Hexagonal, en donde los lados representan los puertos, que permiten ir hacia una capa interior o exterior de la aplicación. Cada componente se podrá conectar con otro componente a través de  estos puertos. La comunicación entre los puertos seguirá siempre un protocolo concreto (por ejemplo un API) que dependerá del objetivo o función que tenga. 

Arquitectura Hexagonal - © Kranio 2021

Arquitectura Hexagonal

Capa de Infraestructura

Esta capa contiene componentes que tienen relación con la integración de otros componentes del microservicio, por ejemplo, un componente de servicio externo como una autenticación de usuario, o un servicio de mensajería (envío de correo), que no es componente core del dominio.

Capa de Aplicación

Esta capa contiene por ejemplo un componente como Spring en Java y en ella se encuentran los diferentes casos de uso.

Capa de Dominio

Esta capa contiene todo el dominio de negocio de la aplicación, es decir, entidades, repositorios, modelo, eventos, servicios.

Arquitectura DDD (Diseño guiado por dominio)

Es un diseño de arquitectura de software donde la lógica de negocio sea el factor determinante de la construcción del software. Permite mapear el negocio en los artefactos del software y organizarlos de tal manera que logre resolver los problemas de negocio. 

El modelado se basa en los casos de uso del negocio. Existe un contexto, que se crea desde la necesidad de resolver un problema. Tenemos que establecer límites para la resolución de este problema, acotando los requerimientos para que no sean redundantes ni hagan más de lo necesario para la solución. Con eso logramos tener una idea del tamaño ideal que debe tener el microservicio. Es importante este punto porque no establecer límites, lleva a tener un microservicio demasiado grande y generar acoplamientos innecesarios. La cohesión es un concepto clave en la delimitación de cada componente.

Niveles o capas de DDD

La estructura está compuesta por capas o niveles bien definidos y estructurados de tal manera que sus componentes no se mezclen entre capas. Por ejemplo aseguramos que, entidades de negocio no estén en capas que no pertenezcan al dominio de negocio, o que la lógica de la persistencia se encuentre en la capa de infraestructura y no en la de presentación.. 

Los niveles o capas interactúan entre sí a través de su propia interfaz, manteniendo encapsulada su lógica interna.

Dependencia de niveles o capas - © Kranio 2021

Las distintas capas se definen de la siguiente manera:

Presentation Layer (UI): Es la capa que interactúa con los distintos clientes. Esta capa es la que muestra y recibe datos. Puede ser representada por una interfaz gráfica de una web o algún dispositivo.

Application Layer: Coordina las acciones a realizar en el dominio. Delega las acciones del negocio a la capa del dominio. Tiene dependencia con la capa de Infraestructura y Dominio.

Domain Layer: Contiene las reglas y lógica de negocio, las entidades y detalles de persistencia. Es el core del software. No tiene dependencias con otras capas del modelo, pero sí, otras capas dependen de esta.

Infrastructure Layer: En esta capa se encuentran implementaciones y funcionalidades encapsuladas que no son del dominio de negocio, por ejemplo conexiones con bases de datos, integraciones con otros servicios externos, servicio de notificaciones de correos, etc. Tiene dependencias con la capa de dominio.

Cohesión y Acoplamiento

Las aplicaciones monolíticas bien diseñadas, tienden a tener una alta cohesión, dado que todos sus componentes están integrados en un mismo contexto, por lo que es fácil comprender la relación de cada componente que está integrado. Para los microservicios es una tarea constante mantener la cohesión dado que al ser un componente aislado y de bajo acoplamiento, hay casos en que existe tanta separación entre ellos que se pierde la cohesión de un servicio y como está relacionado entre los otros microservicios que puedan existir en un contexto determinado.

Los microservicios deben diseñarse alrededor de funcionalidades de la empresa, deben tener acoplamiento flexible y también una alta cohesión funcional. Esto quiere decir que los microservicios deben exhibir un bajo acoplamiento, pero también mantener una alta cohesión. 

Si un componente (microservicio) requiere de un cambio, y este cambio no afecta a los demás microservicios que interactúan con él, es decir, que no deban ser actualizados a causa de este cambio, significa que el microservicio tiene una alta cohesión. Está diseñado con un propósito único y bien definido que permite encapsular el conocimiento de dominio de tal manera que este pueda abstraerse de los clientes que lo consumen. Si este diseño no está bien definido y se desacopla más de lo necesario, es posible que se pierda la cohesión entre componentes.

Ventajas

Agilidad: al estar implementados de forma independiente ,es más fácil administrarlos, ante una falla, se puede actualizar un solo servicio sin tener que volver a implementar toda la aplicación.

Equipos pequeños y centrados: dado que el tamaño de los microservicios es pequeño, para administrarlos es necesario un equipo pequeño. Esto agiliza la productividad dado que al tener equipos pequeños la comunicación fluye de mejor manera. A diferencia de equipos más grandes donde la comunicación suele ser más lenta, produciéndose una menor agilidad.

Base de codigo pequeña: Las aplicaciones monolíticas con el tiempo tienden a crecer y tener nuevas funcionalidades, que complica el mantenimiento del código, al tener que modificar varias capas de la aplicación. Las arquitecturas de microservicios minimizan esta dependencia permitiendo agregar nuevas características fácilmente.

Mezcla de tecnologías: la arquitectura de microservicios permite tener flexibilidad en el lenguaje de cada microservicio, esto mejora la implementación de algún servicio según la tecnología más adecuada para una funcionalidad. También permite tener expertos en una tecnología específica y no tener un equipo forzado a usar una tecnología que no está acostumbrado a usar y que debe investigar.

Aislamiento de errores: los microservicios al ser independientes, si ocurre un error, el error no impide el funcionamiento de los demás microservicios, por lo que no será necesario detener toda la aplicación para corregir los errores.

Escalabilidad Horizontal: no hay una migración de todo el sistema a un hardware con mejores prestaciones, dado que, al ser servicios independientes, se usa el concepto de replicación de servicios. Esta escalabilidad permite agregar recursos adaptables al crecimiento de carga de trabajo.

Desafíos

Complejidad en la gestión: al tener una arquitectura distribuida en varios microservicios, se hace más complejo gestionar la integración de estos. Por lo tanto es necesario contar con herramientas que permitan tener una visión general de todos ellos ante posibles fallas.

Alto consumo de memoria: la arquitectura de microservicios funciona de manera distribuida y cada microservicio es independiente, por lo tanto los recursos deben aumentar, a diferencia de una arquitectura monolítica.

Perfil de desarrollador: Se requiere de desarrolladores con alta experiencia en desarrollo y versionamiento, conocimientos en latencia de red y balanceo de carga.

Inversión de tiempo inicial: al implementar esta arquitectura, requiere un mayor inversión de tiempo dado que requiere de un mayor análisis para separar correctamente los servicios e implementar la comunicación entre ellos.

Visión Personal

Al momento de comenzar a diseñar la arquitectura y sus componentes, debes tener en cuenta que es clave mantener la cohesión para lograr una arquitectura bien definida. Además debes tener un alto manejo y comprensión del negocio, dado que el dominio es el componente más importante y en el que más foco debes poner. Si no tienes un alto conocimiento del negocio, será más complejo implementar arquitecturas como estas. 

Otro punto importante es contar con el equipo idóneo para implementar esta arquitectura. Debe tener una experticia necesaria como para abordar los componentes y herramientas que requiere levantar una arquitectura como esta, además de herramientas adicionales como son el monitoreo de todo sus artefactos.

Necesitas ayuda? Escribenos

Sebastián Sánchez

April 4, 2021