realiza orientada net microservicios libro generalmente entre desarrollo cómo crear comunicación comunicacion basado arquitectura design-patterns architecture microservices aws-api-gateway data-sharing

design patterns - orientada - Intercambio de datos entre microservicios



microservicios c# (4)

Consulte la sección Posible solución en mi pregunta:

La idea es usar la puerta de enlace como un procesamiento de solicitud de puerta de enlace api que almacenará en caché algunas respuestas HTTP de MS1 y MS2 y las usará como respuesta a MS2 SDK y MS1 SDK. De esta manera, no se realiza ninguna comunicación (SYNC OR ASYNC) directamente entre MS1 y MS2 y también se evita la duplicación de datos.

Inspiración: https://aws.amazon.com/api-gateway/ y https://getkong.org/

Arquitectura actual:

Problema:

Tenemos un flujo de dos pasos entre las capas frontend y backend.

  • Primer paso: el frontend valida una entrada I1 del usuario en el microservicio 1 (MS1)
  • Segundo paso: la interfaz envía I1 y más información al microservicio 2

El microservicio 2 (MS2) necesita validar la integridad de I1 ya que proviene de la interfaz. ¿Cómo evitar una nueva consulta a MS1? ¿Cuál es el mejor enfoque?

Flujos que estoy intentando optimizar eliminando los pasos 1.3 y 2.3.

Flujo 1:

  • 1.1 El usuario X solicita datos (MS2_Data) de MS2
  • 1.2 El usuario X persiste los datos (MS2_Data + MS1_Data) en MS1
  • 1.3 El MS1 verifica la integridad de MS2_Data usando una solicitud HTTP de B2B
  • 1.4 El MS1 usa MS2_Data y MS1_Data para persistir y Base de datos 1 y construir la respuesta HTTP.

Flujo 2:

  • 2.1 El Usuario X ya tiene datos (MS2_Data) almacenados en el almacenamiento local / de sesión
  • 2.2 El usuario X persiste los datos (MS2_Data + MS1_Data) en MS1
  • 2.3 El MS1 verifica la integridad de MS2_Data usando una solicitud HTTP de B2B
  • 2.4 El MS1 usa MS2_Data y MS1_Data para persistir y Base de datos 1 y construir la respuesta HTTP.

Enfoque

Un posible enfoque es utilizar una solicitud HTTP B2B entre MS2 y MS1, pero estaríamos duplicando la validación en el primer paso. Otro enfoque será duplicar datos de MS1 a MS2. sin embargo, esto es prohibitivo debido a la cantidad de datos y su naturaleza de volatilidad. La duplicación no parece ser una opción viable.

Una solución más adecuada es mi opinión, será la interfaz para tener la responsabilidad de obtener toda la información requerida por el microservicio 1 en el microservicio 2 y entregarla al microservicio 2. Esto evitará todas las solicitudes HTTP B2B.

El problema es cómo el servicio micro 1 puede confiar en la información enviada por el frontend. Quizás utilizando JWT para firmar de alguna manera los datos del microservicio 1 y el micrervicio 2 podrá verificar el mensaje.

Nota Cada vez que el microservicio 2 necesita información del microservicio 1, se realiza una solicitud http http. (La solicitud HTTP utiliza ETAG y control de caché: max-age ). ¿Cómo evitar esto?

Meta de la arquitectura

El microservicio 1 necesita los datos del microservicio 2 a pedido para poder persistir MS1_Data y MS2_Data en la base de datos MS1, por lo que el enfoque ASYNC que utiliza un agente no se aplica aquí.

Mi pregunta es si existe un patrón de diseño, una mejor práctica o un marco para habilitar este tipo de comunicación de empuje.

La desventaja de la arquitectura actual es el número de solicitudes HTTP B2B que se realizan entre cada micro servicios. Incluso si uso un mecanismo de control de caché, el tiempo de respuesta de cada microservicio se verá afectado. El tiempo de respuesta de cada micro servicios es crítico. El objetivo aquí es archivar un mejor rendimiento y, de alguna manera, utilizar la interfaz como una puerta de enlace para distribuir datos a través de varios microservicios pero utilizando una comunicación de empuje .

MS2_Data es solo un SID de producto similar a SID de entidad o SID de proveedor que el MS1 debe usar para mantener la integridad de los datos.

Solución posible

La idea es usar la puerta de enlace como un procesamiento de solicitud de puerta de enlace api que almacenará en caché algunas respuestas HTTP de MS1 y MS2 y las usará como respuesta a MS2 SDK y MS1 SDK. De esta manera, no se realiza ninguna comunicación (SYNC OR ASYNC) directamente entre MS1 y MS2 y también se evita la duplicación de datos.

Por supuesto, la solución anterior es solo para UUID / GUID compartido a través de micro servicios. Para datos completos, se utiliza un bus de eventos para distribuir eventos y datos a través de servicios de manera asíncrona (patrón de fuente de eventos).

Inspiración: https://aws.amazon.com/api-gateway/ y https://getkong.org/

Preguntas relacionadas y documentación:


Por la pregunta y los comentarios, entiendo que está intentando reorganizar los bloques para mejorar el rendimiento del sistema. Como se describe en los diagramas, sugiere que en lugar de microservice1 consultando microservice2, la puerta de enlace consultará microservice2 y luego microservice1, que le proporcionará la información de microservice2.

Como tal, no veo cómo esto aumentaría significativamente el rendimiento del sistema, sino que el cambio parece simplemente mover la lógica.

Para remediar la situación, debe mejorarse el rendimiento del microservicio crítico2. Se puede hacer mediante la creación de perfiles y la optimización del software microservice2 (escala vertical) y / o puede introducir el equilibrio de carga (escala horizontal) y ejecutar microservice2 en varios servidores. El patrón de diseño que se utilizará en este caso es el patrón de equilibrio de carga de servicio .


Puede considerar cambiar la forma de sincronización de la comunicación b2b a la asincrónica usando el patrón de publicación-suscripción. En esa situación, la operación de los servicios será más independiente y es posible que no necesite realizar solicitudes b2b todo el tiempo.

La forma en que lo hace más rápido en el sistema distribuido es a través de la desnormalización. Si ms2data cambia raramente, por ejemplo, lo lee más que reescribiendo, tiene que duplicarlo en todos los servicios. Al hacer esto, reducirás la latencia y el acoplamiento temporal. El aspecto de acoplamiento puede ser incluso más importante que la velocidad en muchas situaciones.

Si ms2data es una información sobre el producto, entonces ms2 debería publicar el evento ProductCreated que contenga ms2data en un bus. Ms1 debe estar suscrito a este evento y almacenar ms2data en su propia base de datos. Ahora, en cualquier momento ms1 requiere ms2data, simplemente lo leerá localmente sin la necesidad de realizar solicitudes a ms2. Esto es lo que significa el desacoplamiento temporal. Cuando sigue este patrón, su solución se vuelve más tolerante a fallos y apagar ms2 no influirá en ms1 de ninguna manera.

Considere leer una buena serie de artículos que describan los problemas detrás de la comunicación de sincronización en la arquitectura de microservicios.

Preguntas de SO relacionadas aquí y aquí que tratan problemas bastante similares, considere echar un vistazo.


Sin embargo, es difícil juzgar la viabilidad de cualquier solución sin mirar "dentro" de las cajas:

  • Si lo único que le importa aquí es evitar que la interfaz pueda alterar potencialmente los datos, puede crear una especie de "firma" del paquete de datos enviado por MS2 a la interfaz y propagar la firma a MS1 junto con el paquete. La firma puede ser un hash del paquete contatenado con un número pseudoaleatorio generado de manera determinista a partir de una semilla compartida por los microservicios (por lo que MS1 puede recrear el mismo número pseudoaleatorio que MS2 sin la necesidad de una solicitud HTTP B2B adicional, y luego verificar la integridad del paquete).

  • La primera idea que me viene a la mente es verificar si se podría modificar la propiedad de los datos. Si MS1 debe acceder con frecuencia a un subconjunto de datos de MS2, PUEDE ser posible mover la propiedad de ese subconjunto de MS2 a MS1.

  • En un mundo ideal, los microservicios deben ser completamente independientes, cada uno con su propia capa de persistencia y un sistema de replicación en su lugar. Usted dice que un corredor no es una solución viable, entonces ¿qué pasa con una capa de datos compartida?

¡Espero eso ayude!