En el post anterior, vimos algunos de los retos de implementar transacciones distribuidas y cómo implementar el patrón de Saga utilizando el enfoque Evento/Coreografía. En este artículo, vamos a hablar de cómo abordar algunos de sus problemas como transacciones complejas o dependencias cíclicas de eventos utilizando otro tipo de implementación de Saga llamado Comando u Orquestación.

 

Lógica de secuenciación de comandos y orquestación de Saga

En el enfoque de orquestación, definimos un nuevo servicio con la única responsabilidad de decir a cada participante qué hacer y cuándo. El sitio patrón de la saga El orquestador se comunica con cada servicio en un estilo comando/respuesta indicándoles qué operación debe realizarse.

Veamos cómo queda utilizando nuestro ejemplo anterior de comercio electrónico:

Command/Orchestration flow

  1. Servicio de pedidos guarda una orden pendiente y pide a Order Saga Orchestrator (OSO) que inicie un crear transacción de pedido.
  2. OSO envía un Ejecutar el pago comando para Servicio de pagoy responde con un Pago ejecutado mensaje
  3. OSO envía un Preparar pedido a Stock Service, y éste responde con un comando Pedido preparado mensaje
  4. OSO envía un Entregar pedido a Delivery Service, y éste responde con un Pedido entregado mensaje

En el caso anterior, Order Saga Orchestrator conoce cuál es el flujo necesario para ejecutar una transacción de "crear orden". Si algo falla, también se encarga de coordinar la reversión enviando órdenes a cada participante para deshacer la operación anterior.

Una forma estándar de modelar un orquestador saga es una Máquina de Estado donde cada transformación corresponde a un comando o mensaje. Las máquinas de estado son un patrón excelente para estructurar un comportamiento bien definido, ya que son fáciles de implementar y particularmente grandes para las pruebas.

 

Retroceso en el Mando/Orquestación de Saga

Las reversiones son mucho más fáciles cuando se dispone de un orquestador que coordina todo:

  1. Servicio de existencias responde a OSO con un Agotado mensaje;
  2. OSO reconoce que la transacción ha fallado e inicia el rollback
    1. En este caso, sólo se ejecutó con éxito una operación antes del fallo, por lo que OSO envía un Reembolso Cliente comando para Servicio de pago y establecer el estado del pedido como fallido

 

Ventajas e inconvenientes del uso de Saga Mando/Diseño de orquestación

Las sagas basadas en la orquestación tienen varias ventajas:  

  • Evitar dependencias cíclicas entre servicios, ya que la el orquestador de la saga invoca a los participantes de la saga, pero los participantes no invocan al orquestador
  • Centralizar la orquestación de la transacción distribuida
  • Reducir la complejidad de los participantes, ya que sólo tienen que ejecutar/responder órdenes.
  • Más fácil de implantar y probar
  • La complejidad de la transacción sigue siendo lineal cuando se añaden nuevos pasos
  • Las retrocesiones son más fáciles de gestionar
  • Si tiene una segunda transacción que desea cambiar el mismo objeto de destino, puede ponerla fácilmente en espera en el orquestador hasta que finalice la primera transacción.

Sin embargo, este enfoque sigue teniendo algunos inconvenientes, uno de ellos es el riesgo de concentrar demasiada lógica en el orquestador y acabar con una arquitectura en la que el orquestador inteligente dice a los servicios tontos lo que tienen que hacer.

Otro inconveniente de la orquestación basada en Saga es que aumenta ligeramente la complejidad de su infraestructura, ya que tendrá que gestionar un servicio adicional.

Saga Patrón Consejos

Crear un Id único por transacción

Disponer de un identificador único para cada transacción es una técnica habitual para la trazabilidad, pero también ayuda a los participantes a disponer de una forma estándar de solicitarse datos mutuamente. Utilizando un Id de transacción, por ejemplo, el Servicio de Entrega podría preguntar al Servicio de Existencias dónde recoger los productos y comprobar con el Servicio de Pagos si el pedido se ha pagado.

Añadir la dirección de respuesta dentro del comando

En lugar de diseñar a sus participantes para que respondan a una dirección fija, considere la posibilidad de enviar la dirección de respuesta dentro del mensaje, de esta forma permitirá a sus participantes responder a múltiples orquestadores.

Operaciones idempotentes

Si estás utilizando colas para la comunicación entre servicios (como SQS, Kafka, RabbitMQ, etc.), personalmente te recomiendo que hagas tus operaciones Idempotentes. La mayoría de esas colas podrían entregar el mismo mensaje dos veces.

También puede aumentar la tolerancia a fallos de su servicio. A menudo, un error en un cliente puede desencadenar/reproducir mensajes no deseados y estropear la base de datos.

Evitar las comunicaciones síncronas

A medida que avanza la transacción, no olvides añadir en el mensaje todos los datos necesarios para la ejecución de cada operación. El objetivo es evitar llamadas síncronas entre los servicios sólo para solicitar más datos. Esto permitirá a tus servicios ejecutar sus transacciones locales incluso cuando otros servicios estén desconectados.

La desventaja es que su orquestador será ligeramente más complejo, ya que tendrá que manipular las solicitudes/respuestas de cada paso, así que sea consciente de las ventajas y desventajas.

Si tiene alguna pregunta, no dude en hacérmela en @deniswsrosa

Autor

Publicado por Denis Rosa, Defensor del Desarrollador, Couchbase

Denis Rosa es un Developer Advocate para Couchbase y vive en Munich - Alemania. Tiene una sólida experiencia como ingeniero de software y habla con fluidez Java, Python, Scala y Javascript. A Denis le gusta escribir sobre búsqueda, Big Data, AI, Microservicios y todo lo que pueda ayudar a los desarrolladores a hacer una aplicación hermosa, más rápida, estable y escalable.

4 Comentarios

  1. ¿Existe una aplicación?

    1. He aquí una alternativa a una máquina de estados como implementación: https://github.com/bertilmuth/requirementsascode. Me alegro de que me haga saber su opinión.

  2. Hola, en tu visualización has utilizado Message Broker y canales. Así que parece que Sage Publicar en el canal de corredor. Y por ejemplo Payment Subscriber hacer ese canal y recibir ese mensaje. Después de que se debe enviar el resultado a otro canal para Saga. Así que es PUB/SUB MQ. Así que si el servicio de pago está fuera de línea, Saga debe proivde alguna lógica con el tiempo de espera para la respuesta. ¿Por qué no usamos para ese caso REQ/REP (Request/Response MQ model), o una petición directa al servicio de pago? ¿Así sabremos inmediatamente la respuesta y la disponibilidad del servicio?

Dejar una respuesta