Patrón Saga en Arquitectura de Microservicios


En los últimos tiempos ha tomado mucha importancia el diseño de arquitecturas de software basadas en microservicios. Y aunque en un principio, pueden solucionar y ayudar en muchos problemas, también llevan consigo algunos otros, como el conservar y mantener la integridad de los datos. Para solventar y orientar en este tipo de problemas hemos creado este artículo «Patrón Saga en Arquitectura de Microservicios«.

En este artículo vamos a orientar este patrón de diseño a dos tipos de arquitectura de microservicios, coreografía y orquestación. Por lo que si no tienes claro que significan os recomendamos echar un vistazo a este artículo.

Algunos Patrones de diseño en Microservicios orientados al Dato

En la arquitectura orientada a microservicios, al tener que desacoplar lo máximos la relación entre los diferentes componentes, uno de los mayores retos a los que nos enfrentamos es como mantener la consistencia de los datos. Para ello existen diferentes patrones de diseño que se van a aplicar para trabajar con la gestión de los datos, que dependerá de las necesidades de cada momento, si es una arquitectura que se empieza desde cero, o si es una migración por ejemplo de una arquitectura monolítica a una orientada a microservicios. Entre esos patrones de diseño podemos encontrar:

CQRS:

Este patrón de diseño, cuyas siglas en inglés significan Command Query Responsibility Segregation, separa en responsabilidades de command y query sobre los datos. Ideado por Bertrand_Meyer la idea que surge de este patrón es que cada microservicio debe realizar un comando que realiza una acción o una consulta, pero no ambas. Se podría tener una base de datos para operaciones de lectura y otra para operaciones de escritura/actualizaciones.

Event Sourcing:

Este patrón de diseño es muy común encontrarlo integrado con CQRS. La utilización de este patrón funcionaría enviando mensajes de manera asíncrona entre los microservicios, por ejemplo haciendo uso de kafka, para la comunicación entre ellos.

Base de Datos por Servicio:

En una arquitectura de microservicios, cada uno debe de estar lo más desacoplado posible. Es por ese motivo por el que tener una base de datos en común podría ser muy complicado y difícil de mantener. Diferentes bases de datos se podrán escalar de manera independiente en función de las necesidades, algunas operaciones deberán de realizarse tras consultar otras, por lo que habría que mantener su aislamiento; diferentes microservicios diferentes necesidades, de esta manera incluso se podrán utilizar bases de datos orientadas a columnas, de grafos, etc…

Transaction log tailing:

Este es otro patrón para ayudar a conseguir transacciones distribuidas, la idea detrás de este patrón es seguir el registro de transacciones en la base de datos, y cada cambio publicarlo como un evento.

Saga:

Este patrón que es el tema de discusión en nuestro artículo Arquitectura de Microservicios: Patrón Saga, podríamos decir que es una secuencia de transacciones mediante algún tipo de evento. Lo veremos en profundidad en el siguiente punto.

¿Qué es el patrón Saga?

Vamos a ver primero un pequeño ejemplo para intentar entenderlo mejor.

Tenemos una tienda virtual, en la que cada cliente paga por un dinero virtual para gastar en la tienda. Con cada pedido nos tenemos que asegurar que el cliente tiene suficiente dinero para poder realizar ese pago. Por lo que hemos visto, nuestras transacciones no pueden ser ACID, ya que nuestra arquitectura tiene dos microservicios con una base de datos por servicio, y por lo que vemos las transacciones van a depender de varios servicios.

Por lo que en nuestra arquitectura nos vamos a encontrar con el problema de como tratar con transacciones que dependen de otros servicios. Podríamos definir Saga como una secuencia de transacciones locales, en la que cada transacción local actualiza mediante algún tipo de evento la siguiente transacción que se debe realizar. Si se da el caso en el que una transacción falla, entonces la saga tiene que ejecutar una serie de transacciones para poder deshacer los cambios que fueron realizados y dejar todas la información de forma consistente, es decir, debe realizar una compensación.

Se podría definir Saga como una secuencia de transacciones locales, en la que cada transacción local actualiza mediante algún tipo de evento la siguiente transacción que se debe realizar.

Podríamos encontrar Sagas en dos diseños de microservicios, Coreografía y Orquestación.

Patrón Saga con Orquestación

Orquesta
Orquesta

Podríamos definir una orquestación en microservicios, como aquella arquitectura en la que un coordinador gestiona las transacciones a realizar. Haciendo el simil con una orquesta de música, tendrías los músicos que son coordindos por el director.

Basándonos en el ejemplo que hemos comentado antes, vamos a realizar una arquitectura orquestación. En nuestra tienda tenemos dos microservicios, Order Service y Client Service. Cada uno tiene su propia base de datos. El funcionamiento sería un cliente realiza un pedido (Order Service) y se envía un evento a Client Service para analizar si tiene saldo.

Vamos a mirar el flujo de un pedido.

Orquestación Saga | Patrón Saga en Arquitectura de Microservicios
Orquestación Saga

El diagrama anterior muestra el flujo de un pedido por parte de un cliente teniendo un orquestador entre los microservicios. Como se puede ver la pieza que se encarga de dirigir todas las llamadas entre los microservicios es el orquestador.

Flujo:

  • 1.- El cliente ordena un pedido.
  • 2.- El servicio guarda en base de datos estado «pendiente de confirmación».
  • 3.- El servicio pedido realiza una petición al orquestador para comenzar la transacción.
  • 4.- El orquestador envía una petición a actualizar el saldo del cliente.
  • 5.- El servicio actualiza el saldo del cliente en base de datos.
  • 6.- Se envía una información con el saldo disponible del cliente al orquestador.
  • 7.- El orquestador envía la respuesta al servicio pedido.
  • 8.- El servicio order actualiza el estado a «pedido envíado»

Este sería el «happy path» de un pedido pero qué pasaría si el cliente no tiene saldo, habría que hacer un rollback, que al tener un orquestador sería bastante sencillo. Básciamente el servicio de cliente devolvería «Saldo insuficiente» y habría que cambiar el estado del registro a «fail».

Rollback en una Orquestación con Saga

En nuestra tienda se da el caso que el cliente no tiene suficiente saldo para pagar el artículo por lo que vamos a implementar un rollback o un sistema de compensación en nuestra arquitectura de orquestación, y en nuestro caso en el flujo cambiarían los puntos 6, 7 y 8.

Patrón Saga: Compensación | Patrón Saga en Arquitectura de Microservicios
Patrón Saga: Compensación
  • 6.- Se envía un mensaje con que el saldo del usuario es insuficiente.
  • 7.- El orquestador envía la respuesta al servicio pedido con el saldo insuficiente
  • 8.- El servicio order actualiza el estado a «saldo insuficiente.»

Como hemos podido ver un rollback o compensación con un patrón saga en una orquestación es bastante sencilla de realizar.

Ventajas y desventajas de hacer uso del patrón Saga en Orquestación

Al implementar una orquestación vamos a conocer de una manera fácil el flujo que va a llevar cada transacción, al estar comunicado cada servicio con una pieza central que es el «orquestador». Además la complejidad de las transacciones se va a mantener linear y es evitan las dependencias cíclicas.

Todo esto se consigue gracias a una pieza central que se encarga de orquestar toda la arquitectura (podría ser conductor), pero si esta pieza contiene mucha lógica, su mantenimiento se hará más complejo.

Patrón Saga con Coreografía

Ballet
Ballet

En una coreografía, cada bailarín funciona de manera independiente realizando una secuencia de pasos, que se encuentran enmarcados dentro de un sistema, para entre todos conseguir un objetivo. Con este símil podríamos definir una coreografía en Arquitectura de Software, en la que cada servicio o microservicio se comunicará con otros a través de eventos para decidir la siguiente acción a realizar.

A diferencia de una orquestación, aquí no tendremos una pieza central en la que se «orquestará» la siguiente acción o paso a realizar, sino que se enviarán eventos, que en este caso serán procesados por ejemplo kafka.

Con un patrón Saga será muy importante un ID para cada transacción de modo, que cuando se envíen eventos, todos los servicios que escuchan sepan en todo momento a que transacción corresponde.

Patrón Saga en Coreografía | Patrón Saga en Arquitectura de Microservicios
Patrón Saga en Coreografía

El proceso o flujo que se seguirá desde que un cliente realiza una petición será la siguiente:

  • 1.- El cliente ordena un pedido.
  • 2.- El servicio guarda en base de datos estado «pendiente de confirmación».
  • 3.- El servicio pedido realiza una petición mediante un mensaje.
  • 4.- El servicio cliente escucha la petición y guarda en base de datos la actualización del saldo del cliente
  • 5.- El servicio envía un mensaje con el saldo disponible.
  • 6.- El servicio pedido (Order Service), analiza el mensaje recibido, el cual lleva informado que el cliente tiene saldo suficiente.
  • 7.- Se actualiza la base de datos y se envía el pedido.

Este sería el proceso normal de la realización de un pedido de un cliente, pero que sucdería en una coreografía si el cliente no tiene saldo, vamos a verlo.

Rollback en una Coreografía con Saga

El anterior proceso, sería el típico proceso en el que todo ha ido bien, pero al igual que nos paso con el ejemplo en orquestación, como sería una compensación si nuestro cliente no tiene saldo suficiente.

Una compensación en una coreografía es algo más complejo que con una orquestación, a no ser que el flujo sea parecido al de nuestro ejemplo con 7 pasos. Cuanto más pasos tenga nuestro flujo más complejo es realizar un sistema de compensación.

A continuación se muestran los pasos que se llevarían para hacer un rollback de nuestro ejemplo de coreografía, en el caso en el que el cliente no tenga saldo suficiente:

Saga Coreografía: Compensación
Saga Coreografía: Compensación
  • 6.- Se envía un mensaje con que el saldo del usuario es insuficiente a un broker de kafka.
  • 7.- El Servicio Order Service recibe ese mensaje y actualiza el estado a «saldo insuficiente.»

Ventajas y desventajas de hacer uso del patrón Saga en Coreografía

Implementar un patrón Saga en una coreografía es bastante sencillo, cada servicio dependerá de otro del que se habrá comunicado mediante algún tipo de evento para llevar a cabo alguna transacción. Hasta este punto es bastante fácil, este sistema funcionará muy bien con arquitecturas en las que se lleven pocas transacciones, como ha sido nuestro ejemplo.

Pero qué sucederá con sistemas en las que se tengan muchas transacciones, imagina, que tuvieras más de 15 pasos para gestionar tus transacciones. En ese caso sería muy complejo saber qué servicios van a escuchar o recibir qué eventos, y además implementar un sistema de compensación sería todavía más complejo.

Conclusión

En entrada Patrón Saga en Arquitectura de Microservicios,hemos podido ver como aplicar este patrón en dos diferentes escenarios de Orquestación y Coreografía, con sus Pros y sus Contras. Por lo que para aplicar uno u otro escenario habrá que tener en cuenta el caso de uso a resolver así como el número de transacciones que se van a ejecutar como el número de pasos que serán necesarios.

Si te ha gustado este artículo quizás te interesen:

Seguridad para desarrolladores en Java

Orequestación VS Coreografía

Kafka en una arquitectura de microservicios

Síguenos en nuestras redes sociales facebook y twitter.


5 pensamientos sobre “Patrón Saga en Arquitectura de Microservicios

  1. Interesante articulo, en este contexto.. tengo una pregunta: que llegaria a ser el Orquestador? un microservicio escuchando peticiones desde un API o como se comunicaria con los otros servicios?

    1. Hola Mauricio Trigo,

      Podríamos definir un Orquestador, como aquel que se encarga de gestionar todas las peticiones que le llegan, por ejemplo, Conductor de Netflix es un buen Orquestador, gestiona y procesa las peticiones en función de lo que se necesite. Un microservicio que escucha peticiones el cual tiene un API expuesta podría configurarse para realizar y manejar peticiones, por lo que podría funcionar como orquestador. Para comunicarse con otros servicios lo podría hacer mediante mensajes, por ejemplo Kafka, o incluso peticiones Rest, o por gRPC.

  2. Hola Mauricio Trigo,

    Podríamos definir un Orquestador, como aquel que se encarga de gestionar todas las peticiones que le llegan, por ejemplo, Conductor de Netflix es un buen Orquestador, gestiona y procesa las peticiones en función de lo que se necesite. Un microservicio que escucha peticiones el cual tiene un API expuesta podría configurarse para realizar y manejar peticiones, por lo que podría funcionar como orquestador. Para comunicarse con otros servicios lo podría hacer mediante mensajes, por ejemplo Kafka, o incluso peticiones Rest, o por gRPC.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *