Cómo unir sistemas con estado y de origen de eventos (y vencer al gorila)

Tiene un nuevo y brillante sistema CQRS, está "completo" y está a punto de comenzar las pruebas de integración. Y el gorila de las 800 libras que dormía en la esquina durante las discusiones de tu dominio se despierta.

Sin un solo vistazo a sus diagramas de dominio completos, historias de usuarios interesantes, maquetas de interfaz de usuario o criterios de aceptación bien documentados, estalla a través del "límite de contexto" de línea de puntos que se suponía que lo retrasaría.

El gorila arrasa alrededor de las entidades destructoras del edificio, reduciendo el valor a escombros, desarraigando agregados y, en general, destruyendo todo consenso sobre el proyecto. Gorila, tu nombre es Legacy Integration.

¡Hola chicos! ¡No puedo esperar para ver cómo su aplicación RESTful de microservicio se integra con este sistema ERP a medida de treinta años! Espero que les guste COBOL. (Imagen cortesía de

Los sistemas heredados y la integración de procesos pueden hundir un proyecto ejecutado de otra manera perfectamente. Es una migraña monstruosa de un problema que solo se enseña en la escuela de los golpes duros. También es un problema que, como desarrollador, enfrentará en su carrera (si aún no lo ha hecho) cuando comience a trabajar con empresas y dominios suficientemente establecidos.

Por supuesto, si tienes suerte, todavía no has comenzado a codificar, o al menos todavía es temprano en el proceso, cuando el gorila se despierta. O, si eres inteligente, ves al gorila escondido debajo de la pantalla de la lámpara en la esquina y, frotando las cicatrices de tu último encuentro, evitas su alboroto inevitable al incorporarlo a tu arquitectura desde el principio.

Manejo de sistemas heredados

Como Subdirector de Arquitectura de la Oficina de Sistemas de Información de Investigación de la UCLA, soy responsable de cerrar muchas brechas de sistema y datos. UCLA cuenta con una cartera de décadas de procesos y sistemas comerciales heredados en torno a la investigación que se enfrenta a cualquier intento de "interrumpir" estos enfoques tradicionales con nuevas tecnologías.

Lo más desalentador, esta tubería está conectada con el iceberg impenetrable ocasional de datos heredados que a menudo requiere disputas en tiempo real.

Oh buen señor! Un iceberg de datos! No, espera, esto es solo un fatberg. Me alegro de haber optado por una carrera en código en lugar de saneamiento. (Crédito de la imagen: The Associated Press)

En mi oficina, se nos ha encomendado la tarea de proporcionar integración en estos sistemas heredados a un ritmo cada vez mayor. También estamos aumentando nuestros sistemas transaccionales a medida para manejar los procesos de pequeñas empresas.

Para nuestros propios sistemas, generalmente seguimos el patrón de microservicio. Estamos incorporando más complejidad, como el diseño controlado por dominio (DDD) y el abastecimiento de eventos, cuando sea necesario. Nuestro desafío clave para estos sistemas es la integración heredada en sistemas de persistencia de estado.

Acercarse a la integración

Voy a resumir nuestro enfoque en los próximos párrafos. Así es como hemos abordado uno de los problemas que surgen de la transición de un sistema de eventos, particularmente un sistema de eventos híbrido, a uno que es puramente impulsado por el estado.

Un principio clave que los implementadores a menudo pierden es que el abastecimiento de eventos no debe usarse en todas partes. Esto es según Greg Young, a quien se le atribuye ampliamente la introducción del patrón de arquitectura de software "abastecimiento de eventos".

En nuestros sistemas, utilizamos el abastecimiento de eventos para cumplir requisitos específicos. A veces, esto hace que nuestras aplicaciones tengan un estado que puede residir fuera del flujo de eventos. Además, algunos de nuestros desencadenantes de eventos provienen de cambios de estado del sistema fuente poco confiables. Esto exigiría una gran cantidad de corrección de eventos post-hoc y "rewind-replay" para corregir si tuviéramos que depender solo de la secuencia del evento.

Una solución escéptica

La solución que se nos ocurrió para esto es la que llamo el "Suscriptor escéptico". El Suscriptor escéptico aborda el problema de la "falta de fiabilidad" en el lado del evento del sistema, al menos desde la perspectiva de la máquina de estado heredada. También aborda los sistemas que pueden perder la generación de eventos debido a problemas de datos heredados externos:

  1. El origen del evento puede generar eventos que no den como resultado cambios de estado relevantes para la máquina de estado heredada. Desde su perspectiva, estos son eventos "falsos positivos"
  2. El origen del evento puede fallar al generar eventos para cambios en el estado que son relevantes para la máquina de estado heredada. Desde su perspectiva, estos son eventos "perdidos" u "omitidos"
  3. Los eventos pueden no generarse en absoluto debido a errores o errores en la fuente original del evento. Esto sucede particularmente en las secuencias de extracción-transformación-carga (ETL) de los repositorios de datos heredados. Desde cualquier perspectiva, estos son eventos realmente "omitidos"

El enfoque de Suscriptor escéptico aborda estas preocupaciones al desconfiar del flujo de eventos. Trata la secuencia de eventos como un posible desencadenante o notificación de que el estado ha cambiado, pero también acepta otros posibles desencadenantes. También desconfía de que las notificaciones de cambio de estado sean correctas.

Una vez que se le notifica que el estado puede haber cambiado, el suscriptor notifica a una puerta de enlace de estado que consulta el estado del sistema generado por eventos.

Esta puerta de enlace de estado evalúa el estado contra el último estado conocido (como lo sabía el sistema de suscripción).

Si el cambio es relevante, actualiza el estado del sistema de suscripción y, si es necesario, inicia los procesos comerciales relacionados con el sistema de suscripción.

Damas y gérmenes, el suscriptor escéptico!

Algunos requisitos

Para utilizar este enfoque, su sistema de suscripción debe:

  1. Ya persiste, o puede derivar de lo que persiste, los atributos de estado que le importan del sistema de abastecimiento de eventos
  2. Le permite volver a hacer cómo inyecta datos de cambio de estado

Su sistema de abastecimiento de eventos necesita:

  1. Proporcione un servicio de consulta que represente de manera confiable el estado del sistema e incluya todos los atributos de estado requeridos por el sistema de suscripción
  2. Proporcione datos suficientes en la secuencia de eventos para ubicar los registros relevantes en el servicio de consulta
  3. Admite una "lista" u otra consulta por lotes del servicio de consulta

El suscriptor escéptico que implemente debe incluir:

  1. Una puerta de enlace de estado que puede consultar el servicio de consulta para un registro particular (controlado por evento) o para obtener una lista de registros (otro activador, para ponerse al día en eventos "perdidos")
  2. State Gateway debe incluir la lógica de comparación de dominio del contexto del sistema de suscripción que descarta registros si, en lo que respecta al dominio de suscripción, no han cambiado
  3. Una implementación de suscripción de evento para llamar a la puerta de enlace por registro desde los eventos
  4. La capacidad de actualizar la capa de persistencia del sistema de suscripción con los cambios (para que no se vuelva a actualizar el mismo registro la próxima vez), como a través de un repositorio

El suscriptor escéptico también puede implementar el inicio de procesos comerciales en el sistema de suscripción.

Si es puramente impulsado por el estado, esto puede ser a través de nuevos registros de proceso persistentes para lanzar los procesos concomitantes. De lo contrario, puede llamar a cualquier API de proceso que esté expuesta.

Si inicia estos procesos empresariales, también debe implementar el bloqueo en la puerta de enlace para que no duplique el inicio del proceso si se produce un evento desencadenante durante el proceso ETL.

Resultados positivos

Hay muchos otros desafíos asociados con la integración de sistemas heredados, especialmente cuando se mueve entre contextos de origen y de estado. Sin embargo, este patrón nos ayuda a minimizar la carga técnica asociada con el mantenimiento de eventos cuando se consumen datos heredados (e irregulares).

Antes de seguir este patrón, habíamos estado trabajando en un enfoque estrictamente basado en eventos. Habíamos perdido el acceso rápido a las oportunidades de soporte ofrecidas por tener un estado directamente editable. Con este patrón, hemos recuperado esas oportunidades. Cuando el sistema heredado se está comportando mal porque no le "gustan" los eventos que está recibiendo, hemos cambiado la carga de modificar el flujo de eventos de alguna manera a una simple modificación de estado.

También hemos agregado una capa de acoplamiento flexible para aislar al sistema de suscripción de la exposición directa a los eventos. Esto permite la redirección de otros disparadores del sistema de suscripción.

Por ejemplo, un ETL heredado puede servir como un disparador de puerta de enlace de estado inicial hasta que esté listo para cambiar a una secuencia de eventos. Y lo hemos hecho sin complicar demasiado el servicio CQRS al implementar el suscriptor escéptico intersticial como una entidad independiente.

Aquí hay un consejo profesional para los científicos de datos y los ingenieros que los atienden: si implementa la persistencia políglota en el repositorio de suscripción, también puede construir un almacén de documentos que ya se filtró automáticamente a los cambios de datos que reflejan un proceso comercial significativo.

Finalmente, en el caso de que un evento sea "omitido" o "omitido", tenemos que seguir una ruta de soporte a pedido fácil. O bien volvemos a notificar al suscriptor acerca de ese registro (si sabemos qué registro perdió un evento), o realizamos una consulta de "sistema completo" de recuperación (si no estamos seguros).

Podemos hacer esto sin tener que tocar la secuencia del evento. Esto significa que otras aplicaciones de suscripción no se verán afectadas por la actividad de soporte.

Pensamientos finales

No es el adecuado para cada problema (o incluso para la mayoría de los problemas). Pero es una gran solución para aprovechar el acoplamiento flexible y otros beneficios posteriores del abastecimiento de eventos y CQRS, al tiempo que minimiza la sobrecarga de soporte para solucionar problemas de flujos de datos heredados. Esto permite que nuestros desarrolladores pasen más tiempo escribiendo nuevas aplicaciones y aumenta nuestro valor para nuestros consumidores.

Si disfrutaste esta publicación, haz clic en el botón de abajo y dame algunos aplausos para que más personas la vean. ¡Gracias!

Jonathan es el Subdirector de Arquitectura y Operaciones en el departamento de Sistemas de Información de Investigación de la UCLA. Después de obtener un título en Física de la Universidad de Stanford, pasó más de 10 años trabajando en arquitectura de sistemas de información, mejora de procesos empresariales basados ​​en datos y gestión organizacional. También es el fundador de Peach Pie Apps Workshop, una compañía que se enfoca en crear soluciones de datos para organizaciones sin fines de lucro.