Come gestire le operazioni transazionali in un'architettura guidata dagli eventi?

4

Sto cercando di arricchire un sistema di e-commerce utilizzando microservices (.NET Core e Kubernetes), event sourcing (Kafka) e CQRS. Il caso d'uso particolare a cui stavo pensando è il seguente.

Esiste un microservizio di inventario progettato per utilizzare CQRS. Gli aggiornamenti vengono inseriti in Kafka come eventi, che il microservizio di inventario consuma per aggiornare la sua vista materializzata e le letture vengono eseguite direttamente sulla vista materializzata. Il problema che sto cercando di risolvere è come gestire gli ordini. Nel mio attuale design, gli ordini vengono creati in un microservizio di ordine che emette quindi eventi che il microservizio di inventario consumerebbe e detrarre l'inventario che faceva parte dell'ordine. Tuttavia, c'è una condizione di gara qui. È possibile che un altro acquirente acquisti gli stessi prodotti prima che l'inventario dall'ordine precedente possa essere detratto.

Come si gestisce questo tipo di operazione transazionale che si estende su microservizi? Ho letto che si dovrebbe verificare lo stock rispetto allo stream anziché la vista materializzata (poiché il flusso è la vera fonte della verità), ma sono un po 'confuso su come sarebbe pratico (dato che il flusso potrebbe essere enorme) . Se ho intenzione di farlo, allora perché ho anche la visione materializzata se non posso fidarmi?

    
posta Raymond Saltrelli 05.09.2018 - 15:47
fonte

4 risposte

2

Nella mia esperienza, la maggior parte delle domande sulla transazione e sui microservizi sono causate dai seguenti due motivi:

  1. I dati transazionali sono collocati in diversi microservizi: questo è errato per definizione. I dati che devono essere modificati devono appartenere allo stesso servizio. Raggruppare i dati giusti nel servizio giusto è molto complicato e devi rifletterci sopra. Se crei microservizi basati su entità (ordini, utenti, inventario, prodotti, ecc.), Troverai lo stesso problema ancora e ancora, inoltre ti ritroverai con N servizi a seconda di altri servizi per raggiungere il loro scopo. Pertanto: inserisci tutti i dati che cambiano in modo transazionale insieme.

  2. L'operazione non è transazionale in primo luogo: stai cercando di risolvere con la tecnologia qualcosa che dovrebbe essere risolto dalle regole aziendali. Questo è il tuo scenario secondo me. Gli ordini e gli inventari non sono transazionali. Ovviamente non vuoi che le persone comprino i prodotti esauriti, ma devi accettare che ci sarà sempre una minima possibilità che ciò accada (e se i tuoi numeri di inventario sono corretti, ma qualcuno nel magazzino lascia cadere una scatola e rompe l'ultimo articolo?). Le aziende hanno affrontato questo tipo di problemi molto più a lungo delle transazioni esistenti. Pertanto, parla al mondo degli affari e chiedi che cosa dovresti fare quando arriva un ordine e sei esaurito. Se è disponibile una corretta gestione delle scorte, probabilmente saprai già quando saranno disponibili nuovi articoli, in modo da poter inviare via email al cliente la nuova data di consegna e offrire un rimborso se non accetta (ad esempio).

Come nota a margine, la frase "un microservizio dell'ordine che emette eventi per dedurre l'inventario dal microservizio di inventario" sembra sbagliato. Potrebbe essere solo la formulazione della frase, ma nel caso in cui, voglio sottolineare che la formulazione suggerisce che ciò che fai sta emettendo un comando, non un evento. Un comando è imperativo, devi dire a qualcuno di fare qualcosa (DeductInventoryCommand). Un evento è qualcosa che è già successo (OrderPlacedEvent).

Idealmente, non vuoi che un microservizio dirizzi a un altro cosa fare, in quanto ciò spezza efficacemente l'autonomia del servizio che riceve il comando. Invece, sviluppa i tuoi servizi per essere in grado di svolgere le loro capacità di business sulla base delle informazioni che "sentono" da altri microservizi, ma in modo autonomo. Un servizio di logistica può ascoltare gli ordini effettuati (e gli ordini annullati) e occuparsi di tutto il processo logistico senza che gli venga detto cosa fare. La fatturazione dovrebbe essere in grado di fare il proprio lavoro senza che gli venga detto cosa fare e così via.

    
risposta data 05.09.2018 - 16:08
fonte
2

Esamina Condizioni di gara non esistono , di Udi Dahan.

It's possible from another buyer to buy the same products before the inventory from the previous order can be deducted.

Sì, quindi cosa fa l'azienda quando ciò accade? Probabilmente esiste un protocollo che potrebbe includere l'ordinazione di maggiori scorte o l'offerta a un cliente di un rimborso e delle scuse o ... ci sono molte possibilità.

I ricordi, le supposizioni e le scuse di Pat Helland sono un'altra importante lettura

Business realities force apologies. To cope with these difficult realities, we need code and, frequently, we need human beings to apologize. It is essential that businesses have both code and people to manage these apologies.

Il computer, dopo tutto, non sta guardando il mondo reale, ma la sua simulazione interna. "Il meglio che un computer può fare è indovinare."

    
risposta data 05.09.2018 - 16:13
fonte
1

It's possible for another buyer to buy the same products before the inventory from the previous order can be deducted.

Questo problema esiste indipendentemente dalla tecnologia che usi. È inerente alla natura temporale del problema. Ci sono due soluzioni: ottimista o pessimista.

pessimista:

Crea una transazione che consente a un'azienda di prenotare azioni. Questo deve essere fatto prima di confermare l'ordine. Il problema con questo è che potresti avere clienti che prenotano le cose e poi non riescono ad ordinare o rilasciare la loro prenotazione. Nel frattempo, potresti perdere le vendite perché i clienti non sono in grado di prenotare tali articoli.

ottimista:

I clienti emettono un ordine e controllano e aggiornano lo stock al momento dell'ordine. Se qualcuno emette una richiesta per un articolo che non può essere soddisfatto, viene restituita una risposta che lo informa. Probabilmente vorrai consentire alla richiesta di specificare se l'ordine debba essere soddisfatto completamente o parzialmente soddisfatto.

In ogni caso, non è possibile separare la richiesta da ordinare e la gestione dell'inventario. Nei sistemi che esistono da decenni, queste richieste di ordini e le risposte sono in genere asincrone. Ciò consente di ordinare e razionalizzare le richieste.

    
risposta data 05.09.2018 - 17:34
fonte
0

Generalmente in eCommerce non controlli il livello delle scorte. Rallenta le cose.

Tuttavia, hai alcuni problemi più grandi.

Non è possibile gestire realmente la prenotazione a livello di scorte con una transazione di database tradizionale. Perché è un umano che fa clic sul processo d'ordine, la transazione sarebbe semplicemente aperta troppo a lungo.

Questo ci lascia invece implementare un sistema di prenotazione di titoli. Non c'è alcun problema con questo. Puoi avere un microservizio di magazzino di fronte al tuo database azionario, o "vista materializzata" in kafka speak, che può prenotare azioni con un messaggio in stile RPC e sapere quando gli articoli sono esauriti.

Un utente che tenti di acquistare un oggetto tenterebbe innanzitutto di riservare lo stock tramite lo StockMicroservice e di sapere che non c'era nessuno disponibile in quel momento.

Penso che il tuo problema principale qui stia cercando di spremere gli eventi di business in eventi di database di streaming di kafka.

Un evento aziendale non sempre determina un cambiamento di stato.

    
risposta data 05.09.2018 - 16:16
fonte