Orquestación de microservicios
¿Cuál es el patrón estándar de orquestación de microservicios?
Si un microservicio solo conoce su propio dominio, pero hay un flujo de datos que requiere que múltiples servicios interactúen de alguna manera, ¿cuál es la manera de hacerlo?
Digamos que tenemos algo como esto:
- Facturación
- Envío
Y por el bien del argumento, digamos que una vez que se ha enviado un pedido, se debe crear la factura.
En algún lugar, alguien presiona un botón en un GUI
"Ya terminé, ¡hagamos esto!". En una arquitectura de servicio monolito clásica, diría que hay un ESB
manejo de esto o que el servicio de envío tiene conocimiento del servicio de facturación y simplemente lo llama.
Pero, ¿cuál es la forma en que la gente afronta esto en este nuevo y feliz mundo de los microservicios?
Entiendo que esto podría considerarse altamente basado en opiniones. pero hay un lado concreto, ya que se supone que los microservicios no deben hacer lo anterior. Por lo tanto, tiene que haber un "¿qué debería hacer en su lugar por definición?", que no esté basado en opiniones.
Disparar.
Book Building Microservices describe en detalle los estilos mencionados por @RogerAlsing en su respuesta.
En la página 43, en Orquestación versus Coreografía, el libro dice:
A medida que empezamos a modelar una lógica cada vez más compleja, tenemos que afrontar el problema de gestionar procesos de negocio que se extienden más allá de los límites de los servicios individuales. Y con los microservicios, alcanzaremos este límite antes de lo habitual. [...] Cuando se trata de implementar este flujo, hay dos estilos de arquitectura que podríamos seguir. Con la orquestación, dependemos de un cerebro central para guiar e impulsar el proceso, de manera muy similar al director de una orquesta. Con la coreografía, informamos a cada parte del sistema de su trabajo y le dejamos resolver los detalles, como bailarines que encuentran su camino y reaccionan ante los demás a su alrededor en un ballet.
Luego, el libro procede a explicar los dos estilos. El estilo de orquestación corresponde más a la idea SOA de servicios de orquestación/tareas , mientras que el estilo de coreografía corresponde a las tuberías tontas y los puntos finales inteligentes mencionados en el artículo de Martin Fowler.
Estilo de orquestación
Bajo este estilo, el libro anterior menciona:
Pensemos en cómo sería una solución de orquestación para este flujo. En este caso, probablemente lo más sencillo sería que nuestro servicio de atención al cliente actuara como cerebro central. Al crearse, se comunica con el banco de puntos de fidelidad, el servicio de correo electrónico y el servicio postal [...], a través de una serie de llamadas de solicitud/respuesta. El propio servicio de atención al cliente puede entonces rastrear dónde se encuentra un cliente en este proceso. Puede comprobar si la cuenta del cliente ha sido configurada, si se ha enviado el correo electrónico o si se ha entregado la publicación. Podemos tomar el diagrama de flujo [...] y modelarlo directamente en código. Incluso podríamos usar herramientas que implementen esto por nosotros, tal vez usando un motor de reglas apropiado. Existen herramientas comerciales para este mismo propósito en forma de software de modelado de procesos de negocio. Suponiendo que utilicemos solicitud/respuesta sincrónica, incluso podríamos saber si cada etapa ha funcionado [...] La desventaja de este enfoque de orquestación es que el servicio al cliente puede convertirse en una autoridad de gobierno central. Puede convertirse en el centro de una red y en un punto central donde la lógica comienza a vivir. He visto que este enfoque da como resultado que una pequeña cantidad de servicios "dioses" inteligentes le digan a los servicios anémicos basados en CRUD qué hacer.
Nota: Supongo que cuando el autor menciona herramientas se refiere a algo como BPM (por ejemplo , Actividad , Apache ODE , Camunda ). De hecho, el sitio web de patrones de flujo de trabajo tiene un impresionante conjunto de patrones para realizar este tipo de orquestación y también ofrece detalles de evaluación de diferentes herramientas de proveedores que ayudan a implementarlo de esta manera. No creo que el autor insinúe que sea necesario usar una de estas herramientas para implementar este estilo de integración; sin embargo, se podrían usar otros marcos de orquestación livianos, por ejemplo, Spring Integration , Apache Camel o Mule ESB.
Sin embargo, otros libros que he leído sobre el tema de Microservicios y, en general, la mayoría de los artículos que he encontrado en la web parecen no favorecer este enfoque de orquestación y, en cambio, sugieren usar el siguiente.
Estilo de coreografía
Bajo el estilo de coreografía el autor dice:
Con un enfoque coreografiado, podríamos simplemente hacer que el servicio de atención al cliente emita un evento de forma asincrónica, diciendo que el cliente creó. El servicio de correo electrónico, el servicio postal y el banco de puntos de fidelidad simplemente se suscriben a estos eventos y reaccionan en consecuencia [...] Este enfoque está mucho más desacoplado. Si se necesita algún otro servicio para llegar a la creación de un cliente, sólo necesita suscribirse a los eventos y hacer su trabajo cuando sea necesario. La desventaja es que la vista explícita del proceso de negocios que vemos en [el flujo de trabajo] ahora solo se refleja implícitamente en nuestro sistema [...] Esto significa que se necesita trabajo adicional para garantizar que se pueda monitorear y rastrear que se hayan hecho las cosas correctas. sucedió. Por ejemplo, ¿sabría si el banco de puntos de fidelidad tuvo un error y por algún motivo no configuró la cuenta correcta? Un enfoque que me gusta para lidiar con esto es crear un sistema de monitoreo que coincida explícitamente con la vista del proceso de negocios en [el flujo de trabajo], pero luego rastree lo que hace cada uno de los servicios como entidades independientes, permitiéndole ver excepciones extrañas asignadas al flujo de proceso más explícito. El [diagrama de flujo] [...] no es la fuerza impulsora, sino sólo una lente a través de la cual podemos ver cómo se comporta el sistema. En general, he descubierto que los sistemas que tienden más hacia el enfoque coreografiado están menos acoplados y son más flexibles y susceptibles de cambiar. Sin embargo, es necesario hacer un trabajo adicional para monitorear y rastrear los procesos a través de los límites del sistema. He descubierto que la mayoría de las implementaciones fuertemente orquestadas son extremadamente frágiles y tienen un mayor costo de cambio. Con eso en mente, prefiero apuntar a un sistema coreografiado, donde cada servicio sea lo suficientemente inteligente como para comprender su papel en todo el baile.
Nota: Hasta el día de hoy todavía no estoy seguro de si la coreografía es solo otro nombre para la arquitectura basada en eventos (EDA), pero si EDA es solo una forma de hacerlo, ¿cuáles son las otras formas? (Consulte también ¿ Qué quiere decir con "basado en eventos"? y Los significados de la arquitectura basada en eventos ). Además, parece que cosas como CQRS y EventSourcing resuenan mucho con este estilo arquitectónico, ¿verdad?
Ahora, después de esto viene la diversión. El libro Microservicios no asume que los microservicios se implementarán con REST. De hecho, en la siguiente sección del libro, proceden a considerar las soluciones basadas en RPC y SOA y, finalmente, REST. Un punto importante aquí es que Microservicios no implica REST.
Entonces, ¿qué pasa con HATEOAS? (Los hipermedia como motor del estado de las aplicaciones)
Ahora bien, si queremos seguir el enfoque RESTful no podemos ignorar a HATEOAS o Roy Fielding estará encantado de decir en su blog que nuestra solución no es verdaderamente REST. Vea la publicación de su blog sobre la API REST. Debe estar basada en hipertexto :
Me siento frustrado por la cantidad de personas que llaman API REST a cualquier interfaz basada en HTTP. ¿Qué hay que hacer para dejar claro en el estilo arquitectónico REST la noción de que el hipertexto es una restricción? En otras palabras, si el motor del estado de la aplicación (y, por tanto, la API) no está controlado por hipertexto, entonces no puede ser RESTful ni puede ser una API REST. Período. ¿Hay algún manual roto en alguna parte que deba arreglarse?
Entonces, como puede ver, Fielding cree que sin HATEOAS no se pueden crear realmente aplicaciones RESTful. Para Fielding, HATEOAS es el camino a seguir cuando se trata de orquestar servicios. Recién estoy aprendiendo todo esto, pero para mí, HATEOAS no define claramente quién o qué es la fuerza impulsora detrás de seguir los enlaces. En una interfaz de usuario, ese podría ser el usuario, pero en las interacciones de computadora a computadora, supongo que eso debe hacerlo un servicio de nivel superior.
Según HATEOAS, el único enlace que el consumidor de API realmente necesita conocer es el que inicia la comunicación con el servidor (por ejemplo, POST/pedido). A partir de este momento, REST conducirá el flujo porque, en la respuesta de este punto final, el recurso devuelto contendrá los enlaces a los siguientes estados posibles. Luego, el consumidor de API decide qué enlace seguir y mueve la aplicación al siguiente estado.
A pesar de lo genial que suena, el cliente aún necesita saber si el enlace se debe PUBLICAR, PUTAR, OBTENER, PATCH, etc. Y el cliente aún necesita decidir qué carga útil pasar. El cliente aún necesita ser consciente de qué hacer si eso falla (reintentar, compensar, cancelar, etc.).
Soy bastante nuevo en todo esto, pero para mí, desde la perspectiva de HATEOA, este cliente o consumidor de API es un servicio de alto nivel. Si lo pensamos desde la perspectiva de un humano, puedes imaginar a un usuario final en una página web, decidiendo qué enlaces seguir, pero aún así, el programador de la página web tuvo que decidir qué método usar para invocar los enlaces. y qué carga útil pasar. Entonces, en mi opinión, en una interacción de computadora a computadora, la computadora asume el papel de usuario final. Una vez más esto es lo que llamamos un servicio de orquestaciones.
Supongo que podemos usar HATEOAS ya sea con orquestación o coreografía.
El patrón de puerta de enlace API
Chris Richardson sugiere otro patrón interesante, quien también propuso lo que llamó un patrón de puerta de enlace API .
En una arquitectura monolítica, los clientes de la aplicación, como navegadores web y aplicaciones nativas, realizan solicitudes HTTP a través de un equilibrador de carga a una de N instancias idénticas de la aplicación. Pero en una arquitectura de microservicios, el monolito ha sido reemplazado por una colección de servicios. En consecuencia, una pregunta clave que debemos responder es ¿con qué interactúan los clientes?
Un cliente de aplicación, como una aplicación móvil nativa, podría realizar solicitudes HTTP RESTful a los servicios individuales [...] A primera vista, esto puede parecer atractivo. Sin embargo, es probable que haya una discrepancia significativa en la granularidad entre las API de los servicios individuales y los datos requeridos por los clientes. Por ejemplo, mostrar una página web podría requerir llamadas a una gran cantidad de servicios. Amazon.com, por ejemplo, describe cómo algunas páginas requieren llamadas a más de 100 servicios. Realizar tantas solicitudes, incluso a través de una conexión a Internet de alta velocidad, y mucho menos a una red móvil de menor ancho de banda y mayor latencia, sería muy ineficiente y daría como resultado una mala experiencia de usuario.
Un enfoque mucho mejor es que los clientes realicen una pequeña cantidad de solicitudes por página, tal vez tan solo una, a través de Internet a un servidor front-end conocido como puerta de enlace API.
La puerta de enlace API se encuentra entre los clientes de la aplicación y los microservicios. Proporciona API que se adaptan al cliente. La puerta de enlace API proporciona una API de grano grueso para clientes móviles y una API de grano más fino para clientes de escritorio que utilizan una red de alto rendimiento. En este ejemplo, los clientes de escritorio realizan varias solicitudes para recuperar información sobre un producto, mientras que un cliente móvil realiza una única solicitud.
La puerta de enlace API maneja las solicitudes entrantes realizando solicitudes a una cierta cantidad de microservicios a través de la LAN de alto rendimiento. Netflix, por ejemplo, describe cómo cada solicitud se distribuye en un promedio de seis servicios de backend. En este ejemplo, las solicitudes detalladas de un cliente de escritorio simplemente se envían mediante proxy al servicio correspondiente, mientras que cada solicitud detallada de un cliente móvil se maneja agregando los resultados de llamar a múltiples servicios.
La puerta de enlace API no solo optimiza la comunicación entre los clientes y la aplicación, sino que también encapsula los detalles de los microservicios. Esto permite que los microservicios evolucionen sin afectar a los clientes. Por ejemplo, se podrían fusionar dos microservicios. Otro microservicio podría dividirse en dos o más servicios. Solo es necesario actualizar la puerta de enlace API para reflejar estos cambios. Los clientes no se ven afectados.
Ahora que hemos visto cómo la puerta de enlace API media entre la aplicación y sus clientes, veamos cómo implementar la comunicación entre microservicios.
Esto suena bastante similar al estilo de orquestación mencionado anteriormente, solo que con una intención ligeramente diferente; en este caso, parece tener que ver con la interpretación y la simplificación de las interacciones.
Intentando agregar los diferentes enfoques aquí.
Eventos de dominio
El enfoque dominante para esto parece ser el uso de eventos de dominio, donde cada servicio publica eventos sobre lo que sucedió y otros servicios pueden suscribirse a esos eventos. Esto parece ir de la mano con el concepto de puntos finales inteligentes, tuberías tontas que describe Martin Fowler aquí: http://martinfowler.com/articles/microservices.html#SmartEndpointsAndDumbPipes
Apoderado
Otro enfoque que parece común es envolver el flujo de negocio en un propio servicio. Donde el proxy organiza la interacción entre los microservicios como se muestra en la siguiente imagen:
.
Otros patrones de la composición.
Esta página contiene varios patrones de composición.
Entonces, ¿en qué se diferencia la orquestación de microservicios de la orquestación de antiguos servicios SOA que no son “micro”? No mucho en absoluto.
Los microservicios generalmente se comunican mediante http (REST) o mensajería/eventos. La orquestación suele asociarse con plataformas de orquestación que le permiten crear una interacción programada entre servicios para automatizar los flujos de trabajo. En los viejos tiempos de SOA, estas plataformas utilizaban WS-BPEL. Las herramientas actuales no utilizan BPEL. Ejemplos de productos de orquestación modernos: Netflix Conductor, Camunda, Zeebe, Azure Logic Apps, Baker.
Tenga en cuenta que la orquestación es un patrón compuesto que ofrece varias capacidades para crear composiciones complejas de servicios. Los microservicios se consideran más a menudo como servicios que no deberían participar en composiciones complejas y más bien ser más autónomos.
Puedo ver que se invoca un microservicio en un flujo de trabajo orquestado para realizar un procesamiento simple, pero no veo que un microservicio sea el servicio orquestador, que a menudo utiliza mecanismos como la compensación de transacciones y el repositorio estatal (deshidratación).
Entonces tienes dos servicios:
- microservicio de factura
- Microservicio de envío
En la vida real, tendrías algo en lo que mantendrías el estado de orden. Llamémoslo servicio de pedidos. A continuación, están los casos de uso de procesamiento de pedidos, que saben qué hacer cuando el pedido pasa de un estado a otro. Todos estos servicios contienen un determinado conjunto de datos y ahora necesitas algo más que haga toda la coordinación. Esto podría ser:
- Una GUI simple que conoce todos sus servicios e implementa los casos de uso ("Ya terminé", llama al servicio de envío)
- Un motor de procesos de negocio, que espera un evento de "ya terminé". Este motor implementa los casos de uso y el flujo.
- Un microservicio de orquestación, digamos el propio servicio de procesamiento de pedidos que conoce el flujo/los casos de uso de su dominio.
- Cualquier otra cosa en la que no haya pensado todavía.
El punto principal de esto es que el control es externo. Esto se debe a que todos los componentes de su aplicación son bloques de construcción individuales, débilmente acoplados. Si sus casos de uso cambian, debe modificar un componente en un lugar, que es el componente de orquestación. Si agrega un flujo de orden diferente, puede agregar fácilmente otro orquestador que no interfiera con el primero. El pensamiento de microservicio no se trata solo de escalabilidad y de crear API REST sofisticadas, sino también de una estructura clara, dependencias reducidas entre componentes y reutilización de datos y funcionalidades comunes que se comparten en toda su empresa.
HTH, Marcos