¿Existe algún patrón de diseño o práctica que pueda usar para ayudar con los servicios que están inactivos o inactivos, mientras que otros son estables?
¿Qué pasa si tengo tres microservicios, y dos de ellos son buenos, y uno muere justo en el medio de una POST? Dos recibirán la POST y uno no. No creo que pueda hacer transacciones porque estoy enviando mis solicitudes a un servicio.
¿Cómo diseño para eso? No quiero datos huérfanos en varias bases de datos.
Respuestas:
Algunas opciones
Use un canal de comunicación persistente
En lugar de HTTP, suelte los mensajes en una cola que esté altamente disponible y sea persistente. Por ejemplo, Kafka. Mientras el servidor de destino esté disponible en algún momento, recibirá el mensaje.
Ahora tiene el compromiso de aprovisionar y administrar un subsistema complejo (la cola). Así que asegúrese de analizar si esto vale la pena.
Retroceso y reintento
Haga que la persona que llama mantenga la solicitud fallida (posiblemente persistió en el disco) y vuelva a intentarlo periódicamente. En este caso, es importante distinguir entre su solicitud que causa un bloqueo y el servicio que simplemente no funciona. El primero probablemente se deba a un error y debe registrarse ... los reintentos probablemente no harán la diferencia hasta que se realice una corrección.
Detectar y compensar
Una tarea periódica verifica las condiciones de coherencia entre microservicios. Por ejemplo, la falla registra todo el camino para dirigir las consultas API según sea necesario. Si descubre un problema (por ejemplo, hay un pedido pero el envío nunca recibió la lista de empaque), realice los pasos de compensación. Esos pasos podrían ser crear un ticket de soporte para una solución manual, o enviar un correo electrónico a alguien, o lo que sea.
Considere alternativas de diseño
Un caso como este probablemente requiera una puerta de enlace API para administrar las llamadas a los microservicios afectados. De esa manera, usted controla qué tácticas se usan para mitigar este problema. Probablemente no desee cargar a los clientes con esos detalles de implementación. Ver Patrón de interruptor de circuito .
Debido a que los microservicios son independientes, siempre existirá algún caso de falla que pueda resultar en inconsistencia. Tienes que estar preparado para hacer arreglos manuales cuando surjan.
Si necesita una consistencia fuerte, entonces los microservicios no serán adecuados. Si aún necesita escalabilidad, es posible que desee buscar fragmentos donde los datos relacionados se puedan ubicar en el mismo fragmento para garantizar la coherencia. Todavía puede escalar IO agregando fragmentos.
Si necesita una fuerte consistencia y no tiene problemas de escalabilidad, simplemente use servicios monolíticos. Use las bibliotecas como límites dentro de su aplicación para separar las preocupaciones.
fuente
Creo que lo que está describiendo es el problema del consenso: no desea comprometerse a menos que cada participante en la transacción distribuida diga que la operación fue exitosa. La solución simple a esto es el compromiso de dos fases. Esencialmente, organiza la transacción en cada sistema hasta que cada uno informa que la preparación fue exitosa (Fase 1). Si cada participante en la transacción devuelve el éxito, se le pide a cada uno que se comprometa; si alguno de ellos devuelve un error, se emite una reversión (Fase 2). Hay una arruga en esto que lo lleva a la solución de Compromiso trifásico más compleja. Puede leer una descripción mucho mejor de cada uno aquí:
http://the-paper-trail.org/blog/consensus-protocols-two-phase-commit/
http://the-paper-trail.org/blog/consensus-protocols-three-phase-commit/
fuente