Modelli di persistenza per l'approvvigionamento di eventi

1

Sono incuriosito dal pattern Sourcing di eventi ma sto cercando di progettare un modello di sourcing di eventi e metterlo in forma concreta .

Prima di tutto, voglio assicurarmi di comprendere i principali casi d'uso di questo modello. Poiché lo capisco , uno utilizza l'individuazione degli eventi per acquisire le modifiche di stato nella tua app in diversi momenti, in modo che tu possa:

  • Riproduci gli eventi per riavvolgere l'app in uno stato precedente; o
  • Riproduci eventi in un altro ambiente per ricreare la produzione a un certo punto nel tempo e risolverlo

Quindi, prima di tutto, se ho frainteso i principali casi d'uso per l'event sourcing, o se mi mancano quelli principali, per favore cominciamo a correggermi!

Supponendo che io sia più o meno in pista, il mio vero ostacolo mentale sta nel modello di persistenza degli eventi.

  • Quanti database ci sono in un sistema di approvvigionamento di eventi? Ci sono due database (uno per la memorizzazione delle entità principali e un altro per la memorizzazione degli eventi)? O c'è solo un database in cui tutte le entità sono gli eventi persistenti stessi?
  • Come acquisisci gli eventi (e li proteggi!) per cose che sono totalmente al di fuori del controllo dell'app? Ad esempio: lo stato di alcune API di terze parti con cui la tua app si integra o un broker di messaggi (e lo stato di tutti i suoi messaggi / code) con cui la tua app si integra, argomenti della riga di comando runtime passati nella tua app, ecc.?
  • Come funziona il meccanismo di riproduzione attualmente ? Quindi hai alcune entità. Hai eventi che descrivono le modifiche di stato a tali entità. Puoi leggere quegli eventi (e / o le entità che rappresentano) dal database, ma poi hai bisogno di qualcosa per scrivere effettivamente quegli eventi da qualche altra parte. Quindi questo "replayer" tratta solo ogni evento successivo come aggiornamento di un'entità esistente?

Il mio tentativo migliore (finora):

L'entità (i):

// Groovy pseudo-code
class Order {
    Long id
    Long userId
    Long paymentMethodId    // Perhaps an ID to a 3rd party system that
                            // is PCI compliant, etc.

    // Constructors, getters/setters, etc.
}

// Each 'Order' has 1+ 'OrderLineItems'
class OrderLineItem {
    Long id
    Long orderId
    Long productId    // 'Product' is yet another entity, etc.
    Integer quantity

    // Constructors, getters/setters, etc.
}

L'evento:

abstract class BaseEvent<ENTITY> {
    Date occurredOn
    Date recordedOn
    ENTITY entity

    BaseEvent(ENTITY entity) {
        super()

        this.occurredOn = new Date() // now
        this.entity = entity
    }
}

class OrderEvent extends BaseEvent<Order> {
    // Perhaps some other metadata about order events

    OrderEvent(Order order) {
        super(order)
    }
}

OK, questo è un buon passo nella giusta direzione, ma ancora non mi aiuta a capire come il "meccanismo di riproduzione" sarà in grado di caricare OrderEvents da un database, e in realtà "riprodurli" in inserisci un altro database in uno stato particolare che rappresenta un singolo punto nel tempo.

    
posta smeeb 05.11.2015 - 02:41
fonte

2 risposte

2

I want to make sure that I understand the main use cases of this pattern.

Un altro bel caso d'uso descritto da Fowler è lo storage distribuito. Un cluster di sistemi con database in memoria sono aggiornati tra loro attraverso un flusso di eventi.

How many databases are there in an event sourcing system? Are there two databases (one for storing main entities, and another for storing the events)? Or is there just one database where all entities are the persisted events themselves?

Le entità principali e gli eventi sono oggetti separati ed entrambi sono persistenti, nello stesso o in database differenti.

How do you capture events (and persist them!) for things that are totally outside the app's control?

Avrai bisogno di avvolgere qualsiasi sistema esterno con un gateway. Il gateway deve essere in grado di gestire qualsiasi elaborazione di riproduzione eseguita dal sistema Event Sourcing. Vedi sezioni "Aggiornamenti esterni / Query / Interazioni" della descrizione di Fowler di questo modello.

How does the replay mechanism actually work?

Prendi l'esempio base di Fowler:

Ogni oggetto evento ha un metodo 'processo' per eseguire l'aggiornamento richiesto. Un replay funziona così:

for each Shipping Event e, in ascending order of e.occurred:
    e.process();
    
risposta data 11.11.2015 - 11:26
fonte
1

Quanti database ci sono in un sistema di approvvigionamento di eventi?

Non ha importanza. Puoi avere tutto in un unico database o dividerlo, così come potresti dividere i dati per un negozio online in un database con gli utenti e un database con i prodotti, se lo desideri.

Come fai a catturare gli eventi (e a persistere!) per cose che sono totalmente al di fuori del controllo dell'app?

Persistere sullo stato delle code non è qualcosa che dovresti fare, a meno che non fraintenda la tua domanda. Per quanto riguarda l'API o la riga di comando di terze parti, è sufficiente catturare un evento nel punto in cui si verifica.

Se disponi di un'API di terze parti che devi controllare (ad esempio, interrogare il prezzo esatto di un prodotto nel momento in cui viene effettuato l'ordine), puoi lavorare con esso in riproduzione se l'API può gestirlo o archiviare i dati dalla parte esterna in modo da avere tutti i dati necessari nel vostro evento. Per questo esempio, puoi richiedere l'API per il prezzo nel momento in cui è stato registrato l'evento o archiviare il prezzo nel tuo evento in modo da non aver bisogno dell'API esterna.

Come funziona davvero il meccanismo di riproduzione?

Hai eventi che funzionano su oggetti di dominio. Se si dispone di un elenco di eventi relativi a un ordine, si consente a ciascun evento di operare sull'Ordine a cui sono correlati. Ricorda che un evento memorizzato è fondamentalmente solo un mucchio di dati. Usando questi dati, i tuoi oggetti possono quindi ripetere le azioni che hanno fatto.

    
risposta data 05.11.2015 - 09:18
fonte

Leggi altre domande sui tag