En Apiumhub trabajamos con muchos clientes que buscan montar soluciones que son complejas en muchas áreas técnicas y definimos para cada caso la arquitectura que más se adapta a sus necesidades. Las necesidades de un software a nivel arquitectural no se basan sólo en cumplir las expectativas de escalabilidad, rendimiento y fiabilidad. Esos son la punta del iceberg. Tenemos que tener en cuenta lo que ya hay hecho, el coste de desarrollar sobre lo nuevo y los costes de mantenimiento de la arquitectura. Estos hacen que un proyecto funcione o caiga en el olvido. Aunque últimamente hay una cierta moda de una arquitectura orientada a microservicios, diciendo que es el SOA perfecto ya que cada microservicio se comunica con los demas mediante una interfaz que es agnóstica del lenguaje (o plataforma) y cada uno tiene su propia y única responsabilidad.

Pero, a pesar de todo, esta descripción sólo concuerda con un tipo de microservicio en concreto llamado microservicio físico.

 

Microservicios? 

 

El microservicio físico es una unidad separada y pequeña de software con una única responsabilidad que se despliega sola. Podemos tener un microservicio de gestión de usuarios, uno de gestión de posts de un blog o incluso uno que verifica que los otros microservicios están arrancados.

Un microservicio físico es muy barato, pero el coste de mantener distintos microservicios en el desarrollo de una aplicación hace que a corto plazo sea inmantenible, además de que rompe unos cuantos criterios de la arquitectura.

El coste de una arquitectura de microservicio tanto en diseño como en producción es muy alto.
No hay que sobrearquitecturizar: la mayoría de los módulos lo más probable es que se desplieguen bajo el mismo factor.
El desarrollo es más complejo porque, además de tener en cuenta la lógica de dominio, lo más probable es que nos encontremos con problemas de comunicación y transaccionalidad entre servicios.

Además, hay un criterio básico del software que no se cumple: Red Bar, Green Bar y Refactor.

En el desarrollo del software, primero tenemos que encontrar una forma de feedback rápida. Está demostrado que la mejor forma de feedback en un software es con tests unitarios en un monolito, porque el coste del desarrollo de un monolito en un plazo corto es bajísimo. Cuando tenemos el método de feedback, cumplamos las especificaciones, escribamos código que funcione para el cliente. Luego, refactoricemos.

 

¿Qué quiere decir refactorizar una pieza de software?

Comúnmente nos referimos a sacar código duplicado a un lugar en común y ponerlo bajo test por separado.

En arquitectura del software, cuando llegamos a refactorizar, se trata de que el coste de mantener el código del monolito empieza a ser alto, por lo que hay que sacarlo fuera para que el equipo pueda trabajar en un codebase estable.

Entonces los pasos, demostrados más simples, son empezar en un monolito y cuando el coste empiece a ser alto, sacar servicios de ello. El problema está en saber qué sacar y dónde.

En cambio, si seguimos las reglas del Domain Driven Design, está bastante claro que es lo que hay que sacar fuera porque ya estamos definiendo las responsabilidades de cada pieza de nuestro software de forma encapsulada.

  • ¿Qué hace el modelo? Aplica la lógica de dominio del programa.
  • ¿Qué hace un repositorio? Persistir el estado del programa.
  • ¿Qué hace un servicio de dominio? Gestiona el cambio y la coherencia de nuestro dominio.
  • ¿Qué hace un servicio de aplicación? Gestiona la transaccionalidad y la coherencia entre dominios.

Este es el punto, donde por simplicidad, podríamos definir un microservicio como servicio de dominio o de aplicación. Pero, ¿realmente tiene sentido que un servicio de dominio sea un microservicio? Este caso tendría muchos costes, ya que gestionar la transaccionalidad de forma remota mediante comunicación REST, o por colas es costosa, porque hay que tener en cuenta todo el problema de la comunicación y podrían corromperse los datos de forma muy sencilla.

Por lo que sólo queda un candidato, el servicio de aplicación.

Tiene sentido que sea nuestro microservicio porque se ocupa de la gestión entre transacciones de dominio, por lo que la composición compleja ya está hecha y sólo tenemos que comunicarnos con un servicio al que hay que decirle “crea un post cuyo creador es este usuario”. Podemos meter ese mensaje en una cola sin preocuparnos de que, aunque no llegue, no se corrompa el estado de la aplicación, porque de él no dependen otras llamadas.

Es básicamente encapsulación. Tenemos piezas de código independientes lógicamente, temporalmente y que se comunican mediante una interfaz que no depende de la implementación interna.

Por lo que sí, los microservicios lógicos son una gran idea por defecto, pero los microservicios físicos son probablemente una muy mala idea que hay que repensar dos veces.

Hay tecnologías como AKKA que permiten publicar los applicacion services como actores, que por configuración, aunque el código sea monolito, se pueden deployar de forma remota, permitiendo escalabilidad horizontal simple de un monolito.

Si el acceso a estas tecnologías no es posible, podemos publicar nuestro monolito en todas las máquinas que hagan falta ya que el coste de poner en producción un monolito no es alto con tecnologías como Docker, y aunque quizá perdemos recursos en disco o en memoria, son mucho más baratos que perderlos en desarrollo, mantenimiento y evolución del producto, que es de donde vamos a vivir.

 

Si te gustó este artículo sobre microservicios, te puede interesar:

Los beneficios de la tecnología Scrum 

Beneficios de la tecnología Agil

Metodo Kanban Principios y Ventajas 

Beneficios de la integración contínua

Beneficios de TDD

¿Porque debería usar Docker en mi proyecto de desarrollo?

Beneficios de la pruebas unitarias

Los elementos de las buenas pruebas de usuario 

La importancia de las retrospectivas en la metodología Ágil 

Suscríbete a nuestro newsletter para estar al día de los eventos, meet ups y demás artículos!