Soy relativamente nuevo en la arquitectura de microservicios. Tenemos una aplicación web de tamaño moderado y estoy sopesando los pros y los contras de dividirla en microservicios en lugar de un sistema monolítico que ahora estamos avanzando.
Por lo que yo entiendo, considere los microservicios A
y B
cada uno de los cuales depende de un subconjunto de datos que tiene el otro. Si se publica un mensaje A
diciendo que algo ha cambiado, B
puede consumir ese mensaje y replicar una copia local de A
la información y usarla para hacer lo que sea B
necesario.
Sin embargo, ¿qué B
pasa si falla / falla y, después de un tiempo, vuelve a subir? Durante ese tiempo de inactividad, A
ha publicado dos mensajes más. ¿Cómo B
sabe cómo actualizar su copia local de A
la información de?
De acuerdo, si B
es el único consumidor de A
la cola, puede comenzar a leerla una vez que vuelva a estar en línea, pero ¿qué pasa si hay otros consumidores de esa cola y se consumen esos mensajes?
Como ejemplo más concreto, si un Users
servicio tiene su dirección de correo electrónico actualizada mientras un Billing
microservicio está inactivo, si el Billing
microservicio vuelve a funcionar, ¿cómo sabe que el correo electrónico se ha actualizado?
Cuando los microservicios vuelven a funcionar, ¿se transmite diciendo "Hola, estoy de vuelta, dame toda tu información actual?"
En general, ¿cuáles serían las mejores prácticas de la industria para la sincronización de datos?
fuente
Orders
necesita saber algo al respectoUsers
?Respuestas:
Desafiaría toda su idea de "enviar los datos a todos los demás microservicios".
Por lo general, si un servicio de facturación necesita una dirección de correo electrónico, solo le pide al servicio de dirección la dirección de correo electrónico del cliente específico. No necesita mantener una copia de todos los datos de la dirección ni se le informará si algo cambia. Simplemente pregunta y obtiene la respuesta de los datos más recientes.
fuente
Después de investigar un poco más, me topé con este artículo del que saqué algunas citas que creo que son útiles para lo que quiero lograr (y para cualquier lector futuro). Esto ofrece una manera de adoptar un modelo de programación reactiva sobre un modelo de programación imperativo.
Abastecimiento de eventos
Lo que esto ayuda a lograr es que si un microservicio deja de funcionar y se publican otros eventos pertinentes y , por ejemplo, otros eventos de ese microservicio los consumen, cuando ese microservicio vuelve a funcionar, puede referirse a esto
event store
para recuperar todos los eventos que se perdió durante el período en que cayó.Apache Kafka como corredor de eventos
Considere el uso de Apache Kafka, que puede almacenar y enviar miles de eventos por segundo y tiene mecanismos incorporados de replicación y tolerancia a fallas. Tiene un almacén persistente de eventos que pueden almacenarse en el disco de forma indefinida y consumirse en cualquier momento (pero no eliminarse) del Tema (cola de fantasía de Kafka) en el que se entregaron.
De hecho, cuando los consumidores se identifican con Kafka, Kafka registrará qué mensajes fueron entregados a qué consumidor para que no se vuelva a enviar.
Sagas
Esto es cuando entra en juego la saga. Una saga es una secuencia de transacciones locales. Cada transacción local actualiza la base de datos y publica un mensaje o evento para activar la próxima transacción local en la saga. Si una transacción local falla porque viola una regla comercial, la saga ejecuta una serie de transacciones compensatorias que deshacen los cambios realizados por las transacciones locales anteriores. Lea esto para más información.
fuente
Incluso si llego tarde, quisiera poner mis dos centavos en el argumento porque creo que es un punto importante cuando desea evaluar e diseñar una arquitectura de microservicios basada en eventos. Cada microservicio sabe exactamente cuáles son los eventos que impactan en su estado y puede esperarlos. Cuando el microservicio no está disponible, debe haber un componente que guarde los mensajes que se necesitan del microservicio fallido hasta que no pueda "consumirlos". De hecho, este es un modelo de "productor / consumidor" y no uno de "publicación / suscripción". Los corredores de mensajes (como Kafka, RabbitMQ, ActiveMQ, etc.) suelen ser la mejor manera de lograr este comportamiento (a menos que no esté implementando algo diferente, como el abastecimiento de eventos) proporcionando colas persistentes y un mecanismo de bloqueo / bloqueo.
Ahora el microservicio sabe que un mensaje finalmente se entrega pero no es suficiente: ¿cuál es la forma en que espera la entrega de un solo mensaje? ¿Puede administrar la entrega de múltiples copias de la misma notificación de evento? Esto es cuestión de entrega semántica (al menos una vez, exactamente una vez)
Pensamientos finales):
Cuando agrega un microservicio a su arquitectura que necesita consumir eventos de otros, debe hacer la primera sincronización
Incluso el corredor puede fallar, en este caso los mensajes se pierden
Para ambos escenarios, sería útil tener mecanismos simples para rehidratar su estado de microservicio. Podría ser una API REST o un script que envíe mensajes, pero lo más importante es tener medios para realizar alguna tarea de mantenimiento
fuente
Puede reemplazar una cola de eventos normal con un modelo de editor / suscriptor, donde el
A
servicio publique un nuevo mensaje del tema T y elB
tipo de microservicios se suscribirá al mismo tema.Idealmente
B
, sería un servicio sin estado y utilizaría un servicio de persistencia separado, de modo que unaB
instancia de servicio fallida se reemplazaría generando una o másB
instancias de servicio para continuar su trabajo, leyendo el mismo servicio de persistencia compartido.fuente
Si desea que B pueda acceder a los datos internos de A, sería mejor simplemente darle acceso a las bases de datos internas de A.
Sin embargo, no debe hacer eso, el objetivo de una arquitectura orientada al servicio es que el servicio B no puede ver el estado interno del servicio A y está limitado a realizar solicitudes a través de las API REST (y viceversa).
En su caso, podría tener un servicio de datos del usuario, que tiene la responsabilidad de almacenar todos los datos del usuario. Otros servicios que desean usar esos datos solo lo solicitan cuando lo necesitan y no guardan una copia local (lo cual, por cierto, es realmente útil si piensa en el cumplimiento del RGPD). El servicio de datos del usuario puede admitir operaciones CRUD simples como "Crear nuevo usuario" o "Cambiar nombre para user_id 23" o puede tener operaciones más complejas, "Encuentre a todos los usuarios estándar con un cumpleaños en las próximas 2 semanas y entrégueles estado de prueba premium ". Ahora, cuando su servicio de facturación necesite enviar un correo electrónico al usuario 42, le preguntará al servicio de datos del usuario "¿Cuál es la dirección de correo electrónico de user_id 42", usará sus datos internos con toda la información de facturación para elaborar el correo electrónico y luego podrá pasar el correo electrónico? dirección de correo electrónico y cuerpo a un servidor de correo.
fuente