Cómo Event Sourcing lo ayuda a rastrear el estado de su aplicación

Shutterstock / blancoMocca

El abastecimiento de eventos es una arquitectura de software en la que los cambios en el estado de la aplicación se capturan como una serie de "eventos" almacenados perpetuamente. Si bien la mayoría de los sistemas solo exponen su estado actual, la generación de eventos crea un registro completo de todos los estados anteriores.

Índice de contenidos()

    Los fundamentos

    El abastecimiento de eventos se utiliza a menudo con sistemas de procesos lineales o basados ​​en el tiempo. Una aplicación de pedidos en la tienda puede transferir transacciones entre los estados "pendiente", "aprobado" y "enviado". La transición entre cada estado es un "evento" distinto en el ciclo de vida de ese orden.

    Este sistema podría modelarse utilizando una base de datos relacional tradicional:

    order_id | order_status
    ---------|-------------
    1000     | APPROVED

    En la mayoría de los sistemas, sin embargo, conocer el estado actual no es suficiente. Tu tambien quieres ver Cuándo el pedido ha sido aprobado. Podríamos hacer esto agregando campos adicionales:

    order_id | order_created_time | order_approved_time | order_shipping_time
    ---------|--------------------|---------------------|---------------------
    1000     | 2021-04-30         | 2021-05-01          | NULL

    Ahora está claro que la orden fue creada el 30 de abril y aprobada el 1 de mayo; su expedición aún está pendiente. Para muchas aplicaciones, esta estructura funciona bien. Sin embargo, puede volverse restrictivo a medida que se agregan más estados.

    Echemos ahora un vistazo a este ejemplo reestructurado para usar el abastecimiento de eventos:

    event_id | event_order_id | event_type     | event_timestamp
    ---------|---------------------|----------------|----------------
    2        | 1000                | order.approved | 2021-05-01
    1        | 1000                | order.created  | 2021-04-30

    Las transiciones de estado de los pedidos se han separado en un registro de eventos dedicado. Con este modelo, es trivial agregar un nuevo tipo de evento en el futuro. Si un cliente necesita cancelar un pedido, podemos escribir un archivo. order.cancelled evento en el registro.

    El abastecimiento de eventos también podría usarse para rastrear datos sobre el pedido en sí. Puede agregar tipos de eventos para order.apply_discount o order.process_refund. Puede registrar un evento en cualquier momento creando un nuevo estado para el pedido mientras mantiene accesibles los estados anteriores.

    Reconstruir el estado de un objeto

    Puede determinar el estado actual de un objeto recuperando todos los eventos relacionados con él. Si desea saber si un pedido ha sido aprobado, verifique si su colección de eventos contiene un archivo order.approved evento.

    Puede reconstruir estados históricos exactamente de la misma manera. Si necesita conocer el estado del pedido en una fecha en particular, recupere todos los eventos registrados ese día o antes.

    La fuente de eventos es un modelo incremental que rastrea automáticamente el historial de un objeto. Cualquier cambio en el estado del objeto. debe ser capturado como un evento cronometrado. Cuando utiliza la fuente de eventos, tiene un control de versiones automático y un registro de auditoría completo de las transiciones de estado.

    Si necesita reconstruir el historial de un objeto, puede eliminar todos los eventos creados después de una fecha determinada. Imagine que la cuenta de un usuario se vio comprometida por un atacante que realizó varias acciones en su nombre. En un sistema totalmente impulsado por eventos, es posible eliminar cualquier evento vinculado a ese usuario en un período de tiempo cuestionable. Esto restablecería su cuenta en buena forma.

    Para conservar esta capacidad, debe asegurarse de que los eventos sean inmutables. Una vez que se ha registrado un evento, nunca debe cambiar sus propiedades. Si un evento necesita un ajuste, grabará otro evento para realizar el cambio.

    La inmutabilidad del sistema significa que puede usarlo de manera segura para viajar en el tiempo y reconstruir estados históricos. Si desea reproducir su base de datos como estaba hace dos años, puede descartar todos los eventos registrados en el tiempo intermedio.

    Otro beneficio del abastecimiento de eventos es una mayor visibilidad del estado del sistema. Si un usuario informa un error, puede clonar la base de datos, eliminar nuevos eventos y repetir los pasos desde un punto positivo conocido. El análisis de eventos registrados puede ayudarlo a detectar errores en su base de código.

    Abastecimiento de eventos en el mundo real

    El abastecimiento de eventos tiene la reputación de ser complejo, engorroso y complicado. Históricamente, el abastecimiento de eventos se ha asociado con aplicaciones con requisitos de auditoría rigurosos y una necesidad comprobada de reproducir eventos.

    Sin embargo, no tiene por qué serlo. Si es un desarrollador experimentado, probablemente haya implementado algo parecido al abastecimiento de eventos en el pasado. Cualquier sistema que mantenga un registro de "eventos", como los intentos de inicio de sesión del usuario, las visitas a la página del sitio web o los pasos de procesamiento de pedidos, gravita naturalmente hacia un enfoque basado en eventos, incluso si no está implementando uno intencionalmente.

    La implementación deliberada de la fuente de eventos en el código puede ser complicada. Los desarrolladores generalmente asumen que los datos recuperados de las bases de datos son una representación precisa del estado actual de un objeto. Con el abastecimiento de eventos, los datos recuperados en sí mismos tienen poco valor. Debe "reproducir" los eventos en el código base para crear una representación del estado.

    El abastecimiento de eventos puede resultar en una sobrecarga de rendimiento. En el ejemplo anterior, crear una representación completa del objeto de pedido ahora requiere recuperar muchos más datos. En el modelo tradicional, una sola selección proporciona todos los datos asociados con el pedido.

    También hay otras desventajas. En caso de que algo salga mal, la búsqueda de eventos puede resultar más difícil de resolver. No es posible escribir un parche rápido o reparar manualmente la base de datos. Deberá hacer una transición elegante de sus patrones de eventos asegurándose de que la línea de tiempo histórica permanezca intacta.

    Combinación de abastecimiento de eventos y CQRS

    El abastecimiento de eventos se combina comúnmente con CQRS (Segregación de Responsabilidades de Consultas de Mando). Este modelo admite la separación de comandos (que escribe datos) de consultas (que lee los datos).

    El uso de fuentes de eventos requiere cierto grado de CQRS. Los datos se escriben en la base de datos a través de eventos. Por lo tanto, el modelo de escritura es extremadamente simple: es un registro unidireccional de solo agregar de los eventos que ocurren. Los eventos son una manifestación de los "comandos" descritos por CQRS.

    El modelo de recuperación de datos es completamente independiente. Puede utilizar el sistema de consulta más adecuado para recuperar eventos y superponerlos al estado actual de la aplicación. La comandos (eventos) hacen que el sistema pase a un nuevo estado; Las consultas exponen los aspectos de estado requeridos por su aplicación.

    En otras palabras, los modelos de lectura y escritura no tienen conciencia de cómo funcionan los demás. Las entidades en su base de código (como un pedido) se almacenan como una secuencia de eventos históricos. Los eventos almacenados no se pueden rehidratar en la entidad a la que pertenecen sin saber cómo se deriva el estado de esa entidad. Este conocimiento se implementa dentro del modelo de lectura (consulta), que reporta los datos a su aplicación.

    Esta característica le permite simplificar el nivel de persistencia en una sola inserción de registro para cada operación. Los datos almacenados no tienen que representar con precisión una entidad en particular, ya que el modelo de consulta los manipulará más adelante. Esto contrasta con una base de datos relacional "tradicional" donde los campos de la tabla a menudo están estrechamente alineados con las propiedades de los objetos en la base del código.

    La salida del modelo de consulta se conoce como proyección. Una proyección es una representación datos utilizando una perspectiva diferente a la de su propio sistema de archivo. Cuando se utiliza la fuente de eventos, los datos se almacenan como un flujo de eventos pero proyectado en una representación del estado actual de la aplicación. Esa representación es apátrida, inmutable e idempotente: la creación de la representación no cambia los datos del evento subyacente de ninguna manera.

    Una sola proyección puede tener que interactuar con varios tipos diferentes de eventos. Las proyecciones miran los datos de manera agregada, de una manera que tiene sentido para las funciones de la aplicación. En nuestro ejemplo anterior, una proyección de orden podría producir un objeto contenedor CreatedDate, ApprovedDate es ShippedData propiedad mediante el examen de los eventos asociados con el orden del sujeto.

    Conclusión

    El abastecimiento de eventos es una arquitectura de software especializada con soporte innato para la responsabilidad, la historia y la recreación estatal. El modelo puede simplificar enormemente la implementación de aplicaciones donde estas cualidades son deseables.

    El abastecimiento de eventos también puede ser útil en otros escenarios, aunque se pueden ver rendimientos decrecientes. La adopción de la fuente de eventos requiere que los desarrolladores implementen código para determinar el estado actual, agregando gastos generales que no ocurren en sistemas que solo almacenan el estado actual en su base de datos.

    El abastecimiento de eventos se combina mejor con otras técnicas de arquitectura de software como CQRS, patrón de observación y cualquier consistencia. No es necesario utilizar el suministro de eventos en toda la aplicación; a menudo, los submódulos individuales se beneficiarán del suministro de eventos, mientras que la mayoría de su proyecto se adhiere a una base de datos relacional tradicional.

    Deja una respuesta

    Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

    Subir