Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Arquitecturas orientadas a eventos: de las notificaciones al Event Sourcing

David García
December 17, 2020

Arquitecturas orientadas a eventos: de las notificaciones al Event Sourcing

Los sistemas distribuidos con comunicación asíncrona basada en eventos están de moda y nuestro compañero David García, senior developer, nos habla de ello en esta charla que despide el 2020.

Es un buen momento para repasar conceptos, potenciales problemas y soluciones con un ejemplo que irá evolucionando durante la charla. Hablaremos de tipos de eventos, CQRS, Event Sourcing, consistencia eventual, ordenación, idempotencia, versionado y sagas ¡entre otras cosas!

#CompartimosExperiencias

David García

December 17, 2020
Tweet

More Decks by David García

Other Decks in Technology

Transcript

  1. 1 Arquitecturas orientadas a eventos: de las notificaciones al Event

    Sourcing #CompartimosExperiencias @davgarcia5
  2. Sobre Autentia 2 SOPORTE A DESARROLLO DISEÑO DE PRODUCTO UX

    FORMACIÓN ACOMPAÑAMIENTO AGILE AUDITORIA DE DESARROLLO SOFTWARE A MEDIDA
  3. ⸺ Un poco de teoría ⸺ Modelado ⸺ Notificaciones ⸺

    (CQRS) ⸺ Event-Carried State Transfer ⸺ Event Sourcing ⸺ Conclusiones Contenidos 3
  4. ¿Qué? 5 ⸺ Paradigma de comunicación publicador - suscriptor ⸺

    Evento == unidad de intercambio de información ⸺ Aplicaciones: — Integración en OLTP y tiempo real — Procesamiento y análisis para BI, ML, etc… No en esta charla
  5. ¿Por qué? ⸺ Transparencia de localización ⸺ Múltiples receptores ⸺

    Comunicación asíncrona ⸺ Bajo acoplamiento ⸺ Alta escalabilidad ⸺ Resiliencia 6 Microservicios ⏫Disponibilidad ⏬Consistencia
  6. Conceptos 9 ⸺ Un evento comunica un hecho — Acto

    que ya ha ocurrido, inmutable — No todo mensaje es un evento! — Tiene tipo y esquema flexible/implícito ‒ Metadatos ‒ Payload ⸺ Stream — Secuencia de eventos de una instancia de entidad — Ordenados para no violar invariantes de negocio ⸺ Event journal — Almacenamiento persistente de streams — Append-only https://cloudevents.io/
  7. Tipos ⸺ Notificaciones ⸺ Event-Carried State Transfer — Full vs

    Delta ⸺ Event Sourcing 10 No son patrones de diseño Tener claras necesidades y requisitos CQRS
  8. ⸺ DDD Clientes Pagos Modelado 11 Reservas de teatro Pago

    Reserva Sala Representación Butaca Obra Cliente Descuento Aggregate roots Entities Bounded contexts Concepto Value objects
  9. Notificaciones 13 ⸺ Solución técnica ad-hoc para evitar espera activa

    en proceso largo Pros — Libera recursos durante la espera Cons — Evento sin semántica, anémico — Alto acoplamiento para conseguir resto de información
  10. Notificaciones 14 ⸺ Conseguir resto de información — Endpoint GET

    en productor — Consumidor con cliente REST para invocarlo — Productor online en el momento de consumir Productor Consumidor GET
  11. ⸺ Command Query Responsibility Segregation (CQRS) 15 Command API handler

    Lógica y modelo de dominio Query API handler Lógica de consultas Cliente Write model store Optimizado para integridad Read model store Optimizado para consulta Sync
  12. Event-Carried State Transfer 16 ⸺ Comunicación de cambio de estado

    de una instancia — Completa: todos los atributos de la instancia — Delta: sólo lo que ha cambiado Pros — Consumidor no necesita llamar al productor — Bajo acoplamiento real — Muy escalable — Resiliencia — Baja latencia de queries Cons — Consistencia eventual — Versionado y esquema — Complejidad de operación — Tamaño de los eventos — Tendencia a eventos CRUD — Dual-write ⇒ Inconsistencias
  13. CQRS en ECST 17 Proyección Command API handler Lógica y

    modelo de dominio Query API handler Lógica de consultas Cliente Dual write BD BD Event journal Consumo
  14. Dual write 18 TRANSACCIÓN ⸺ Sin transaccionalidad entre BD y

    event journal ⸺ Solución: patrón Outbox Comando TRANSACCIÓN entidad outbox_entidad INSERT/UPDATE/DELETE INSERT Outbox polling ↺ SELECT Publicar DELETE
  15. Ordenación 19 ⸺ Garantiza invariantes de negocio ⸺ Estados y

    transiciones consistentes — Por parte de la aplicación ‒ Cambio de estado en transacción de BD ‒ Publicar evento si y sólo si todo bien — Por parte del event journal ‒ Consumo en el mismo orden de publicación
  16. Idempotencia 20 ⸺ Una operación repetida sólo tiene efecto la

    1ª vez ⸺ Event journals con semántica “at least once” ⸺ Cuidado con los sistemas externos/proveedores
  17. Consistencia eventual 21 ⸺ No garantizado — ¿Cuándo se propagará

    el cambio? — “Read after write” ⸺ Garantizado — No se pierden cambios — Eventualmente, las lecturas devolverán el valor del último cambio ⇒ Orden ⸺ Consecuencias — Mínima contención — Estrategias para proyecciones desactualizadas ‒ ¿Retry-After? ‒ ¿ETag + If-None-Match?
  18. Versionado 22 ⸺ Estrategias — ¿Es un nuevo tipo de

    evento? ➕ — Múltiples manejadores ❌ ‒ Difícil de mantener a largo plazo — Upcaster ❌ ‒ Lógica para subir versión de eventos antiguos en runtime ‒ Oscuro y complejo — Copy-transform offline ❓ ‒ Si no hay más remedio... ‒ A un nuevo stream y después switch de productores y consumidores — Retro-compatibilidad ‒ Consumidores “tolerant reader” / Ley de Postel ‒ Validación JSON Schema sólo en productor
  19. Consumer Driven Contract Testing 23 ⸺ Los eventos son el

    API — Docs: AsyncAPI + DocGen ⸺ Contrato — Id del stream — Qué datos se consumen y formato — Estructura, no semántica
  20. Event Sourcing 24 ⸺ El event journal es la fuente

    de verdad — No es Event Sourcing si no puedes reconstruir estado a partir del event journal — Histórico de cambios por motivos legales, auditoría, análisis de datos… — Eventos representan hechos relevantes de negocio Pros — Todos los de ECST — Observabilidad, depuración, análisis y trazabilidad — Consultas basadas en el tiempo — Modelo intuitivo y realista — Reintentos, recuperación ante fallos y correcciones Cons — Consistencia eventual — Versionado y esquema — Complejidad de operación — UI basado en tareas — Complejidad de implementación
  21. CQRS en Event Sourcing 25 Command API handler Lógica y

    modelo de dominio Query API handler Lógica de consultas Cliente BD o caché Event journal BD o caché Proyección En BD si stream grande o mezclado con otros En tiempo real con caché si stream pequeño Snapshots! Consumo
  22. CQRS en Event Sourcing Representación Agregada Libres: A1, A2, B1,

    B2 26 Seleccionar butacas: A1, B2 ☑ Butacas seleccionadas: A1, B2
  23. CQRS en Event Sourcing 27 Representación Agregada Libres: A1, A2,

    B1, B2 Orden y repetición Seleccionar butacas: A1, A2 ☑ Seleccionar butacas: A1 Butacas seleccionadas: A1 Butacas seleccionadas: A1, B2
  24. ⸺ Estrategias — Single Writer ‒ Stream de comandos ≈

    Stream de eventos ‒ 1 consumer/stream vs Single-Thread — OCC (Optimistic Concurrency Control) ‒ Versión del modelo == Offset en stream ‒ Publicar evento con chequeo de versión (transaccional) ‒ Reintentar si no coinciden — CRDT (Conflict-free Replicated Data Types) ‒ Conflictos resueltos automáticamente — Manual ‒ Permitir conflictos ‒ Y resolver manualmente Orden 28 Dispersión geográfica y/o temporal RMBR! Orden para garantizar consistencia
  25. Repetición 29 ⸺ Sistemas externos/proveedores — Idempotencia de comandos ‒

    En la lógica de aplicación del propio comando ‒ En el adaptador del sistema externo — Consultas a proveedores ‒ ¿Cómo estaba el dato en un instante pasado? ⸺ Cambios en la lógica de aplicación — ¿Cómo garantizar que una operación repetida da el mismo resultado? ⸺ Cambios en reglas de negocio — ¿Versionado de reglas y de flujos de negocio?
  26. Eventos internos vs externos 30 ⸺ ¿Eventos de Event Sourcing

    == Eventos de dominio? ⸺ Si no: — ¿“Property sourcing”? ❌ — Outbox-pattern — ...para filtrar/transformar eventos internos — ...y publicar eventos externos de dominio Mejor evitar esta situación y usar eventos de dominio puros
  27. Saga 32 ⸺ Patrón de diseño para modelar un proceso

    largo — Múltiples dominios/subdominios/aggregates — Sin transacciones reales para garantizar consistencia — Acciones de compensación para transaccionalidad ficticia ⸺ Beneficios — Modelado explícito — ...para sistemas distribuidos — ...que necesitan escalar
  28. ⸺ Responsabilidades — Control orden — Idempotencia — Invariantes y

    reglas de negocio y temporales Saga 33 Consume Produce Agregada Saga Comandos Eventos Eventos Comandos ⸺ Enfoques — Centralizado / Orquestación — Distribuido / Coreografía
  29. Conclusiones 34 ⸺ Abrazar la consistencia eventual — La información

    tarda tiempo en propagarse — No existe un único estado actual ⸺ ¿Qué nos queda? Agregada “Estado local consistente” Comandos “Lo que va a pasar” Eventos “Lo que ya ha pasado” Agregada “Estado local consistente” Comandos “Lo que va a pasar” Eventos “Lo que ya ha pasado” Agregada “Estado local consistente” Comandos “Lo que va a pasar” Eventos “Lo que ya ha pasado”
  30. Conclusiones 35 ⸺ ¿Qué Event Journal? — Producto dedicado, no

    BD genérica — Poder procesar stream de manera eficiente — Latencia de escritura constante — Semántica “at least once” — Transaccionalidad — Lectura ordenada y a partir de offset — Sin esquema ⸺ Ejemplos: https://softwaremill.com/mqperf/
  31. Conclusiones 36 ⸺ Antipatrones y olores — Casos de uso

    CRUD — Mezclar diferentes modelos de eventos en un mismo flujo — CDC (Change Data Capture), Debezium — Vuelta al ESB ‒ “Smart endpoints and dumb pipes” ‒ Validación fuerte de esquema ‒ Transformaciones — ¿Frameworks? ‒ Eventuate Local ‒ Eventstore2 ‒ Axon Framework & Server ‒ Occurrent
  32. ¿Para qué? 37 ⸺ Para satisfacer necesidad de negocio ⸺

    ...de escalar rápido ⸺ ...de resiliencia y tolerancia a fallos ⸺ ...de desacoplar dominios o subdominios ⸺ ...de mantener histórico de cambios ⸺ ...a cambio de consistencia eventual y complejidad