Uso de mensajería asincrónica para mejorar la disponibilidad

imagen Hola habrozhiteli! Recientemente entregamos un libro de Chris Richardson a la imprenta, cuyo propósito es enseñar cómo desarrollar aplicaciones con éxito utilizando la arquitectura de microservicios. El libro discute no solo las ventajas, sino también las desventajas de los microservicios. Aprenderá en qué situaciones tiene sentido aplicarlas y cuándo es mejor pensar en un enfoque monolítico.

El libro se centra en la arquitectura y el diseño. Está diseñado para cualquier persona cuyas responsabilidades incluyan escribir y entregar software, incluidos desarrolladores, arquitectos, directores técnicos y jefes de departamentos de desarrollo.

Lo siguiente es un extracto del libro Uso de la mensajería asincrónica.

Uso de mensajería asincrónica para mejorar la disponibilidad


Como ha visto, los diversos mecanismos de IPC lo empujan a varios compromisos. Uno de ellos está relacionado con la forma en que IPC afecta la accesibilidad. En esta sección, aprenderá que la interacción sincrónica con otros servicios como parte del procesamiento de solicitudes reduce la disponibilidad de la aplicación. En este sentido, cuando diseñe sus servicios, debe usar mensajes asíncronos siempre que sea posible.

Primero, veamos qué problemas crea la interacción sincrónica y cómo afecta la accesibilidad.

3.4.1. La interacción sincronizada reduce la disponibilidad


REST es un motor IPC extremadamente popular. Puede tener la tentación de usarlo para la comunicación entre servicios. Pero el problema con REST es que es un protocolo síncrono: el cliente HTTP tiene que esperar hasta que el servicio devuelva una respuesta. Cada vez que los servicios se comunican entre sí a través de un protocolo síncrono, esto reduce la disponibilidad de la aplicación.

Para comprender por qué sucede esto, considere el escenario que se muestra en la Fig. 3.15. El servicio de pedidos tiene una API REST para crear pedidos. Para verificar el pedido, recurre a los servicios para consumidores y restaurantes, que también tienen una API REST.

imagen

Crear una orden consiste en esta secuencia de pasos.

  1. El cliente realiza una solicitud HTTP POST / pedidos al servicio de pedidos.
  2. El servicio de pedido recupera la información del cliente al hacer una solicitud HTTP GET / consumer / id al servicio al consumidor.
  3. El servicio de pedidos recupera la información del restaurante ejecutando una solicitud HTTP GET / restaurant / id al servicio del restaurante.
  4. Order Taking verifica la solicitud utilizando información sobre el cliente y el restaurante.
  5. La toma de pedidos crea un pedido.
  6. Order Taking envía una respuesta HTTP al cliente.

Dado que estos servicios usan HTTP, todos deben estar accesibles para que FTGO procese la solicitud CreateOrder. No podrá crear un pedido si al menos uno de los servicios no está disponible. Desde un punto de vista matemático, la disponibilidad de una operación del sistema es un producto de la disponibilidad de los servicios que participan en él. Si el servicio de Pedido y los dos servicios a los que llama tienen una disponibilidad del 99.5%, entonces su disponibilidad general será del 99.5% 3 = 98.5%, que es mucho menor. Cada servicio posterior que participa en la solicitud hace que la operación sea menos accesible.

Este problema no es exclusivo de las interacciones basadas en REST. La disponibilidad disminuye cuando un servicio necesita recibir respuestas de otros servicios para responder a un cliente. Incluso la transición a un estilo de interacción de solicitud / respuesta además de mensajes asincrónicos no ayudará aquí. Por ejemplo, si el servicio de pedidos envía un mensaje al servicio al consumidor a través de un agente y comienza a esperar una respuesta, su disponibilidad se deteriorará.

Si desea maximizar la accesibilidad, minimice la cantidad de interacción sincrónica. Veamos como hacerlo.

3.4.2. Deshágase de la interacción sincrónica


Hay varias formas de reducir la cantidad de interacción sincrónica con otros servicios al procesar solicitudes sincrónicas. En primer lugar, para evitar completamente este problema, todos los servicios se pueden proporcionar con API exclusivamente asincrónicas. Pero esto no siempre es posible. Por ejemplo, las API públicas generalmente se adhieren al estándar REST. Por lo tanto, algunos servicios deben tener API síncronas.

Afortunadamente, para procesar solicitudes sincrónicas, no es necesario ejecutarlas usted mismo. Hablemos de tales opciones.

Uso de estilos de interacción asincrónica

Idealmente, toda interacción debería ocurrir en el estilo asincrónico descrito anteriormente en este capítulo. Imagine, por ejemplo, que el cliente de la aplicación FTGO utiliza un estilo de interacción de solicitud asíncrona / respuesta asíncrona para crear pedidos. Para crear un pedido, envía un mensaje de solicitud al servicio de pedidos. Luego, este servicio intercambia mensajes de forma asíncrona con otros servicios y finalmente devuelve una respuesta al cliente (Fig. 3.16).

imagen

El cliente y el servicio se comunican de forma asíncrona, enviando mensajes a través de canales. Ninguno de los participantes en esta interacción está bloqueado esperando una respuesta.

Dicha arquitectura sería extremadamente robusta, porque el agente almacena los mensajes hasta que su consumo sea posible. Pero el problema es que los servicios a menudo tienen una API externa que utiliza un protocolo síncrono como REST y, como resultado, deben responder de inmediato a las solicitudes.

Si el servicio tiene una API síncrona, la accesibilidad se puede mejorar mediante la replicación de datos. Veamos como funciona.

Replicación de datos

Una forma de minimizar la interacción sincrónica durante el procesamiento de consultas es replicar datos. El servicio almacena una copia (réplica) de los datos que necesita para procesar las solicitudes. Para mantener actualizada la réplica, se suscribe a eventos publicados por los servicios a los que pertenecen estos datos. Por ejemplo, un servicio de pedidos puede almacenar una copia de los datos pertenecientes a los servicios de consumo y restaurante. Esto le permitirá procesar solicitudes para crear pedidos sin recurrir a estos servicios. Tal arquitectura se muestra en la fig. 3.17.

imagen

Los servicios para consumidores y restaurantes publican eventos cada vez que cambian sus datos. El servicio de pedidos se suscribe a estos eventos y actualiza su réplica.

En algunos casos, la replicación de datos es una buena solución. Por ejemplo, el Capítulo 5 describe cómo el servicio de pedidos replica los datos del servicio de restaurante para poder verificar los elementos del menú. Uno de los inconvenientes de este enfoque es que a veces requiere copiar grandes cantidades de datos, lo cual es ineficiente. Por ejemplo, si tenemos muchos clientes, almacenar una réplica de los datos que pertenecen al servicio al consumidor puede no ser práctico. Otra desventaja de la replicación radica en el hecho de que no resuelve el problema de actualizar los datos que pertenecen a otros servicios.

Para resolver este problema, un servicio puede retrasar la interacción con otros servicios hasta que responda a su cliente. Esto se discutirá más a fondo.

Finalizar el procesamiento después de devolver una respuesta

Otra forma de eliminar la interacción sincrónica durante el procesamiento de consultas es realizar este procesamiento en la forma de los siguientes pasos.

  1. El servicio verifica la solicitud solo con la ayuda de los datos disponibles localmente.
  2. Actualiza su base de datos, incluida la adición de mensajes a la tabla OUTBOX.
  3. Devuelve la respuesta a su cliente.

Durante el procesamiento de la solicitud, el servicio no accede sincrónicamente a ningún otro servicio. En cambio, les envía mensajes asincrónicos. Este enfoque proporciona una conectividad deficiente de los servicios. Como verá en el próximo capítulo, este proceso a menudo se implementa como una narración.

Imagine que el servicio de pedidos actúa de esta manera. Crea un pedido con el estado PENDIENTE y luego lo verifica intercambiando mensajes asincrónicos con otros servicios. En la fig. La figura 3.18 muestra lo que sucede cuando se llama a la operación createOrder (). La cadena de eventos se ve así.

  1. El servicio de pedidos crea un pedido con el estado PENDIENTE.
  2. El servicio de pedidos devuelve una respuesta con ID de pedido a su cliente.
  3. El servicio de pedidos envía un mensaje ValidateConsumerInfo al servicio al consumidor.
  4. El servicio de pedidos envía un mensaje ValidateOrderDetails al servicio de restaurante.
  5. El servicio al consumidor recibe un mensaje ValidateConsumerInfo, verifica si el cliente puede hacer un pedido y envía un mensaje al cliente validado al servicio Order.
  6. El servicio del restaurante recibe un mensaje ValidateOrderDetails, verifica la exactitud de los elementos del menú y la capacidad del restaurante de entregar un pedido a una dirección determinada, y envía un mensaje OrderDetailsValidated al servicio Order.
  7. El servicio de pedidos recibe mensajes ConsumerValidated y OrderDetailsValidated y cambia el estado del pedido a VALIDATED.

Y así sucesivamente ...

El servicio de pedidos puede recibir mensajes ConsumerValidated y OrderDetailsValidated en cualquier orden. Para saber cuál recibió primero, cambia el estado del pedido. Si el primer mensaje es ConsumerValidated, el estado del pedido cambia a CONSUMER_VALIDATED, y si OrderDetailsValidated cambia a ORDER_DETAILS_VALIDATED. Después de recibir el segundo mensaje, el servicio de pedido establece el estado del pedido en VALIDADO.

Después de verificar el pedido, el servicio de pedidos realiza los pasos restantes para crearlo, que discutiremos en el próximo capítulo. Una gran parte de este enfoque es que el servicio de pedidos puede crear un pedido y responder al cliente, incluso si el servicio al consumidor no está disponible. Tarde o temprano, el servicio al consumidor recuperará y procesará todos los mensajes pendientes, lo que completará la verificación de los pedidos.

imagen

La desventaja de devolver una respuesta antes de que la solicitud se procese por completo es que hace que el cliente sea más complejo. Por ejemplo, cuando el servicio de pedidos devuelve una respuesta, ofrece garantías mínimas sobre el estado del pedido que se acaba de crear. Responde de inmediato, incluso antes de verificar el pedido y autorizar la tarjeta bancaria del cliente. Por lo tanto, para saber si el pedido se ha creado correctamente, el cliente debe solicitar información periódicamente o el servicio de pedidos debe enviarle un mensaje de notificación. A pesar de la complejidad de este enfoque, en muchos casos vale la pena preferirlo, especialmente porque tiene en cuenta los problemas con la administración de transacciones distribuidas, que discutiremos en el Capítulo 4. En los capítulos 4 y 5, demostraré esta técnica usando el ejemplo del servicio de pedidos.

Resumen


  • La arquitectura de microservicios se distribuye, por lo que la comunicación entre procesos desempeña un papel clave en ella.
  • El desarrollo del servicio API debe abordarse cuidadosa y cuidadosamente. Es más fácil realizar cambios compatibles con versiones anteriores porque no afectan la forma en que trabajan los clientes. Al realizar cambios importantes en la API del servicio, generalmente debe mantener tanto la versión anterior como la nueva hasta que se actualicen los clientes.
  • Existen muchas tecnologías IPC, cada una con sus propias fortalezas y debilidades. La decisión clave en la etapa de diseño es la elección entre llamada a procedimiento remoto sincrónico y mensajes asincrónicos. Los más fáciles de usar son los protocolos síncronos como REST, basados ​​en la llamada de procedimientos remotos. Pero, idealmente, para aumentar la accesibilidad, los servicios deben comunicarse mediante mensajes asincrónicos.
  • Para evitar una acumulación de fallas similar a una avalancha en el sistema, un cliente que usa un protocolo síncrono debe ser capaz de lidiar con fallas parciales, el hecho de que el servicio llamado no está disponible o exhibe alta latencia. En particular, cuando se ejecutan solicitudes, es necesario contar el tiempo de espera, limitar el número de solicitudes vencidas y aplicar la plantilla "Fusible" para evitar llamadas al servicio defectuoso.
  • Una arquitectura que usa protocolos síncronos debe incluir un mecanismo de descubrimiento para que los clientes puedan determinar la ubicación de red de las instancias de servicio. La forma más fácil es centrarse en el mecanismo de descubrimiento proporcionado por la plataforma de implementación: en las plantillas "Descubrimiento del lado del servidor" y "Registro de terceros". Un enfoque alternativo es la implementación del descubrimiento de servicios a nivel de aplicación: las plantillas de descubrimiento de clientes y de autorregistro. Este método requiere más esfuerzo, pero es adecuado para situaciones donde los servicios se ejecutan en múltiples plataformas de implementación.
  • El modelo de mensaje y canal encapsula los detalles de la implementación del sistema de mensajería y se convierte en una buena opción al diseñar este tipo de arquitectura. Más tarde, puede vincular su arquitectura a una infraestructura de mensajería específica, que generalmente utiliza un intermediario.
  • Una dificultad clave en la mensajería es la publicación y actualización de la base de datos. Una buena solución es utilizar la plantilla de publicación de eventos: el mensaje se escribe en la base de datos al principio como parte de la transacción. Luego, un proceso separado recupera el mensaje de la base de datos utilizando la plantilla de Interrogating Publisher o Transactional Log Tracking, y lo pasa al intermediario.

»Se puede encontrar más información sobre el libro en el sitio web del editor
» Contenidos
» Extracto

Para Khabrozhiteley 30% de descuento en libros de pre-pedido en un cupón - Microservicios

Source: https://habr.com/ru/post/458344/


All Articles