Aunque trabajar con microservicios ofrece muchos beneficios, la experiencia ha demostrado que también hay algunos problemas asociados con el uso de los mismos. Es importante tener en cuenta estos problemas para que su impacto se pueda minimizar.
Uno de estos problemas es acertar los límites de los microservicios. Esta ha demostrado ser una de las tareas más díficiles.
Establecer el alcance de los microservicios
Es cierto que si cada microservicio tuviera una única responsabilidad, este problema no sería tan frecuente. Sin embargo definir el alcance de la responsabilidad individual no es fácil.
A continuación consideremos un servicio de pago cuya responsabilidad es aceptar pagos en una plataforma de comercio electrónico. Supongamos que, inicialmente, solo hay dos métodos de pago: tarjetas y cupones, y ambos métodos se implementan en el mismo servicio. ¿Esto esta bien? ¿Es «aceptar pagos» una responsabilidad única o debemos crear diferentes servicios para cada método de pago? ¿Por que parar ahí? ¿Por que no crear un servicio diferente para cada tipo de tarjeta: Visa, Mastercard, AMEX, etc.?
Conocer algunos de los requisitos futuros podría ayudar a tomar una decisión más informada, pero normalmente es un lujo que no tenemos. Por lo tanto, imaginemos que, en función de la información actualmente disponible, decidimos tener un único servicio responsable de aceptar los pagos.
Cambio de Requerimientos
Unas pocas semanas después, surgen nuevos requisitos para aceptar pagos con Paypal y Apple Pay. Ahora parece que implementar estos nuevos métodos de pago en el servicio existente hará que el servicio crezca demasiado y tenga «demasiadas responsabilidades«. A la luz de estos nuevos requisitos, se toma la decisión de dividir la responsabilidad de aceptar pagos en diferentes sevicios de acuerdo con el método de pago.
Los pagos de Paypal y Apple Pay se implementarán con servicios separados, pero, ¿Que hacer con el servicio existente que implementa métodos de pago diferentes? Dado que ahora la responsabilidad se define a nivel de método de pago, el servicio de pao original no es consistente con este nuevo enfoque. Como consecuencia, el servicio debe dividirse en dos nuevos servicios.
Mientras que en una aplicación monolítica, el cambio anterior equivaldría a una refactorización de código relativamente simple, en una arquitectura de microservicio, el código debe trasladarse a un nuevo servicio, lo que normalmente requeriría: nuevo repositorio de código, nuevo flujo de trabajo para integración continua/despliegue, entorno de configuración, computación en la nube, recursos de almacenamiento, etc.
Nombramiento de Microservicios
A medida que cambia el alcance de los microservicios, incluso los nombres se desactualizan. En nuestro ejemplo, suponiendo que el servicio original se llamara «Pago«, el nombre se volvió obsoleto tan pronto como la responsabilidad se definió nuevamente en el lugar de método de pago. En una plataforma donde ahora hay servicios llamados «Paypal» y «Apple Pay», ¿Que representa el antiguo nombre «Pago«?.
Enfoque Heurístico de los Límites de Microservicios
En un entorno de constante cambio, las responsabilidades de algunos servicios inevitablemente deben redefinirse con el tiempo. No hay una regla sobre qué tan grande o pequeño debe ser un microservicio. En ausencia de una solución óptima, un enfoque heurístico basado en la experiencia parece ser nuestra mejor opción.
A continuación algunas sugerencias:
- Si algunas partes del servicio cambian con mucha frecuencia y otras apenas lo hacen, es una señal de que el servicio podría dividirse en dos.
- Las partes de la base de código que requieren pruebas específicas o que tardan más en probarse también están mejor en servicio por sí mismas para que su ciclo de vida no interfiera con otros elementos de la aplicación.
- Las piezas complejas de código también deben tener su servicio para evitar interacciones no deseadas con otros elementos de la base de código que podrían causar errores difíciles de identificar.
- El código para acceder a recursos externos como bases de datos o colas también debe estar encapsulado en su servicio.
Un caso de la vida real
A continuación presentamos un caso de la vida real.
Eurostar ha estado vendiendo boletos de tren entre Londres y otras ciudades europeas durantes 25 años. Hace unos tres años, decidieron migrar su aplicación monolítica a una arquitectura de microservicios, por lo que desarrollamos nuevos servicios como «busqueda», «pago», etc. Claramente, en el contexto de Eurostar, los términos, «busqueda» y «pago» se refería a su único producto, el que se había vendido durante 25 años: los boletos de tren.
Poco después de que se completaran los nuevos microservicios, Eurostar tomó la decisión estratégica de convertirse en una agencia de viajes y vender alojamiento en hoteles y paquetes turísticos además de boletos de tren. Se crearon nuevos servicios «búsqueda de hotel», «check-out en hotel», etc, haciendo que los nombres de los servicios existentes sean inadecuados y cuestionando su alcance, planteando preguntas como ¿Necesitamos un servicio de pago común o deberíamos mantenerlos separados?.
La moraleja es que, las empresas cambian y como consecuencia, los servicios también deben revisarse y refactorizarse.
Este artículo esta basado en Micorservice Boundaries, ¿Tiene alguna consideración adicional para definir los límites de los microservicios?