Microservicios: Otro término cargado de hype

 

O la nueva “solución definitiva” a todos los problemas en el ámbito de la arquitectura del software.

Fowler define los microservicios de una forma muy resumida:

“Un enfoque para desarrollar una sola aplicación como un conjunto de pequeños servicios, cada uno ejecutándose en su propio proceso y comunicándose con mecanismos livianos (a menudo mediante una API HTTP). Estos servicios se basan en las capacidades empresariales y se pueden implementar de forma independiente mediante una maquinaria de implementación completamente automatizada. Existe un mínimo de administración centralizada de estos servicios, que puede escribirse en diferentes lenguajes de programación y utilizar diferentes tecnologías de almacenamiento de datos.”

Otra forma habitual de describir este enfoque es mediante la comparativa del mismo frente a un enfoque más tradicional: el monolítico. Lo que significa enfocar el desarrollo de una aplicación cómo una unidad única.

Cabe recordar, que siempre que nos referimos a aplicación, nos estamos refiriendo a la parte que habitualmente conocemos cómo el backend. Tener uno o varios clientes (véase web y móvil) consumiendo de una API NO es tener una arquitectura basada en microservicios (y sí, he escuchado a más de uno y de dos hacer tales afirmaciones).

El enfoque monolítico es el más tradicional y, en cierto modo, podríamos decir que es el más simple. Una única aplicación, un único proceso que responde a nuestras peticiones, un único deploy por versión y horizontalmente escalable mediante balanceo de carga. Sin embargo, esto también implica que cada vez que queramos hacer un pequeño cambio a nuestra aplicación, tendremos que volver a generar todo el artefacto y realizar un nuevo deploy de la misma (con lo que ello implica). Además, con el crecimiento de dicha aplicación, también crecerá la complejidad de mantenerla correctamente modularizada (segregación de responsabilidades, etc). Y por si esto fuera poco, el escalado de la misma también será completo, así que si nos encontramos con un cuello de botella en uno de los módulo , no tendremos más remedio que escalar toda la aplicación.

Cómo podemos ver, motivos para pasarnos al enfoque de los microservicios no nos faltan. Pero, ¿cuándo es realmente adecuado hacer frente a este proceso de cambio? Y, ¿cuáles son los aspectos negativos de este enfoque?

De hecho, si investigamos un poco por los blogs tecnológicos de las grandes compañías (véase Netflix o Amazon, por ejemplo), veremos que éstas se están centrando mayormente en el enfoque de los microservicios, sin embargo, hay que hacer las cosas con cabeza, amigos. NO todos trabajamos en empresas con las dimensiones de las mencionadas, por lo tanto, no matemos moscas a cañonazos antes de hora.

Y ENTONCES, POR QUÉ MICROSERVICIOS?

Esa es la cuestión. Aquí algunas de las razones:

  1. Forzar la separación de las responsabilidades. Cómo dije antes, cuándo una aplicación empieza a crecer mucho, la mantenibilidad de la misma empieza a caer en picado, la deuda técnica tiende al infinito y el proyecto se vuelve cada vez más legacy. Sin embargo, recurrir al clásico divide & conquer nos facilitará mucho dicha tarea.
  2. Adquisición de una ownership más natural. Cuándo el departamento de desarrollo se empieza a segregar en diferentes equipos, mantener un nivel adecuado de ownership se convierte en una tarea cada vez más complicada. Sin embargo, si nuestra aplicación está formada por diferentes servicios, nos será más fácil que cada equipo sea el propietario de varios servicios y que asuma la responsabilidad de los mismos (decisiones técnicas, desarrollo, monitorización, etc).
  3. Mayor agilidad en el desarrollo. Al poseer solo una pequeña parte del producto global, los equipos puede elegir cuándo quieren deployar o incluso deployar varias veces en un día (CI). Esto hace posible la realización frecuente de pruebas de nuevas funcionalidades así cómo llevar a cabo la realización de tests A/B. Además, esto también abre la posibilidad al uso de diferentes tecnologías que se adecuen a cada uno de los problemas que plantee nuestra aplicación. Por ejemplo, para un módulo de nuestra aplicación nos podría convenir un lenguaje de programación de más bajo nivel o una base de datos no relacional (NoSQL) mientras que para otro módulo nos podría interesar lo completamente opuesto.

 

Y ENTONCES, POR QUÉ NO?

Sin embargo, y por desgracia, no todo es tan bonito como podía parecer. De hecho, sería fácil encontrar aspectos negativos a cada una de las razones anteriormente enumeradas. Veamos algunos ejemplos:

  1. ¿Cómo hacemos la separación de las responsabilidades? Vale, tenemos claro que tenemos que separar nuestra aplicación en diferentes servicios. Pero ahora para y haz el ejercicio de pensar en cómo separarías una de las aplicaciones que consumes a diario (véase Instagram, Facebook, Twitter, etc). Necesitamos un servicio de gestión de fotos? Ese servicio se encargará solo de gestionar las fotos? O el mismo servicio también debería gestionar las etiquetas y las localizaciones de las mismas? A que no es sencillo?
  2. ¿Cómo sincronizamos los cambios de los servicios? Quién no ha tenido dolores de cabeza con los versionados (por ejemplo de una API)? Si ahora separamos nuestra aplicación monolítica en varios servicios y equipos diferentes tienen la ownership de diferentes servicios, cómo lo hacemos para que entre ellos se puedan comunicar con compatibilidad hacía adelante y hacía atrás?
  3. ¿Estamos perdiendo potencial técnico en la compañía? Qué ocurre si tenemos cuatro equipos con cuatro servicios distintos y que cada uno a su vez usa tecnología distinta (lenguaje de programación, tipo de persistencia, etc). De repente nos encontramos con mayores dificultades para mover a nuestros empleados de un equipo para el otro según las necesidades y además se complica la puesta en común de soluciones a problemas habituales, y eso evidentemente no mola.

 

ENTONCES, LOS MICROSERVICIOS NO SON EL FUTURO?

Los microservicios, aunque aún son un enfoque bastante joven en el mundo de la arquitectura del software, ya han presentado resultados positivos en muchísimos proyectos. Sin embargo, cabe recordar aquello de que “una técnica que sea más efectiva para un equipo más hábil no necesariamente va a funcionar para equipos menos hábiles.”
De hecho, un equipo pobre técnicamente tenderá a crear sistemas que serán indudablemente deficientes, y añadir la complejidad que representan los microservicios probablemente se traducirá en un empeoramiento mayor de la situación.

Por otro lado, si somos puristas del XP, siempre podremos recurrir al principio YAGNI y pensar que pasarnos al enfoque de los microservicios sin realmente necesitarlo sería un error de bulto. Sin embargo, la discusión está abierta en la comunidad, y podemos ver cómo grandes iconos del sector presentan opiniones contrariadas, cómo se puede ver aquí y aquí.

 

Tras esta breve introducción a los microservicios, mi objetivo es hacer una serie de artículos en la que podamos ir viendo los aspectos comentados más en detalle, así cómo entrar de lleno en la resolución de las complejidades que este tipo de arquitectura nos presenta y que anteriormente, con el enfoque monolítico, no nos habíamos planteado.