In che modo vengono distribuiti i nuovi contesti con limiti e gli errori vengono risolti in architetture di microservizi "autonomi" basati sui messaggi?

3

Vengo dallo sfondo del monolite, utilizzando un unico grande database relazionale. Dalla mia ricerca, molti sostenitori dell'architettura dei microservizi privilegiano l'architettura basata su eventi piuttosto che su REST. La seguente domanda si applica alla comunicazione interservizi, tra contesti limitati (in termini DDD) e NOT agli eventi all'interno di un BC, né creazione di eventi.

A quanto ho capito, per separare i servizi gli uni dagli altri, un bus di messaggi come RabbitMQ viene usato per pubblicare un evento di dominio, che contiene informazioni relative all'evento, come UserCreated o UserSuspended , e altri limiti i contesti possono farne uso per archiviare i dati di cui hanno bisogno nel proprio database. Ad esempio, un servizio di fatturazione potrebbe richiedere solo user id e status in modo che non generi fatture per gli utenti sospesi. Con questi dati utente "memorizzati nella cache", non è necessario effettuare una chiamata API REST al User BC per ottenere le informazioni. Questo è considerato "autonomo" piuttosto che "autorità".

Un paio di domande:

  1. In che modo possono essere distribuiti nuovi servizi? Nell'esempio sopra, supponiamo che il servizio Utente esista ma che il servizio di fatturazione sia in fase di costruzione. Ha bisogno di seminare il suo database con tutti gli stati utente esistenti. Supponendo che non disponga dell'intera cronologia degli eventi disponibili nel servizio Utente (come con RabbitMQ), ciò significa che deve essere soddisfatta una delle due opzioni: A) Il servizio utente deve fornire un endpoint API che il nuovo servizio di fatturazione può utilizzare nelle sue migrazioni per ottenere gli stati degli utenti. È necessario eseguire ulteriori lavori nel servizio utente se questo endpoint non esiste. Oppure B), lo script di distribuzione / migrazione di fatturazione può rompere le responsabilità una volta e accedere direttamente al database degli utenti. Ma questo significa che gli sviluppatori di Billing devono imparare lo schema dei dati da un altro servizio.
  2. Come possono essere corretti i bug che causano incoerenze? Ad esempio, in qualche modo uno sviluppatore ha rotto l'editore e non sono stati prodotti UserCreated o UserSuspended per un'ora. Il bug viene notato e corretto, ma mancano ancora un'intera ora di eventi. Due possibili soluzioni: A) il dev da User BC pubblica manualmente gli eventi mancanti. Avrebbe bisogno di capire quali eventi sono stati persi (se possibile), quindi scrivere script per costruirli (in termini di tempo). Ciò sarebbe ulteriormente problematico se nuovi eventi già attivati rendessero obsoleti quelli originali mancanti. Oppure B) gli altri contesti limitati potrebbero essere notificati per eseguire script che aggiornano i loro dati tramite l'API dell'utente (restituendo al modello autorità )

Un'altra questione di fondo qui è, nella comunicazione tra servizi, dove è la fonte ultima della verità per eventi esterni? Si trova nel flusso di eventi o nell'API fornita dai contesti limitati?

Mi piace l'idea dei sistemi autonomi per ridurre l'accoppiamento, rimuovere le dipendenze e consentire ai servizi di evolvere più rapidamente, ma temo situazioni che causino incoerenze che non si verifichino > autorevole struttura , dove i dati sono sempre aggiornati tramite chiamate API live. Qualsiasi suggerimento sarebbe molto apprezzato.

    
posta Blossoming_Flower 23.08.2018 - 00:56
fonte

3 risposte

1

Un approccio consiste nel trattare le notifiche (messaggi trasmessi a un consumatore) come ottimizzazione delle prestazioni, piuttosto che come unico canale di comunicazione.

Il discorso di Greg Young su dati Polyglot (2014) descrive questa idea, a partire da circa 25 minuti nel discorso.

the User service needs to provide an API endpoint that the new Billing service can use in its migrations to get user statuses.

Questa è l'idea giusta. Più precisamente, abbiamo bisogno di endpoint e messaggi che descrivono sia la query che la risposta. Si deve prestare particolare attenzione nel definire entrambi, poiché i due estremi della conversazione possono essere dispiegati separatamente - se è necessario supportare l'evoluzione dei messaggi nel tempo, si verificherà occasionalmente in situazioni in cui le distribuzioni non sono d'accordo quale versione dello schema del messaggio è in uso.

the other bounded contexts could be notified to run scripts that update their data via the User's API

Questo è l'approccio che mi aspetterei. Non è necessario necessariamente "notificare" gli abbonati, se il produttore rende gli eventi "nuovi" disponibili sugli endpoint nel solito modo.

Una soluzione comune è che l'endpoint rappresenta un'astrazione di un flusso solo append e ogni utente tiene traccia dell'ultima posizione nello stream che ha elaborato. Consulta la guida di Twitter per Lavorare con le linee temporali

    
risposta data 23.08.2018 - 14:51
fonte
1

In termini generali, BC / servizi sono autonomi ma non individualisti. Collaborano per raggiungere un obiettivo più grande. Pertanto, come regola generale, chiedere ad altri sviluppatori BC di fornire qualcosa non è una cattiva pratica, secondo me. Questo potrebbe richiedere la pubblicazione di un evento (è possibile che la pubblicazione utente sospesa non sia affatto pubblicata, quindi è necessario chiedere agli sviluppatori del servizio di assistenza clienti di pubblicarla) o di fornire una funzionalità di distribuzione.

Rispondere alle tue domande:

  1. "Come possono essere distribuiti nuovi servizi?" Creare una soluzione di sola implementazione per questo scenario. Non lasciare che Billing pasticcia con gli altri dati del servizio. Chiedere all'altro servizio di implementare un'interfaccia ben definita, come IProvideSuspendedUsers. Crea una procedura di distribuzione per la fatturazione che chiama quell'interfaccia e, una volta terminato, rimuovi entrambi i lati dal sistema (altrimenti diventerà qualcosa da conservare per sempre che nessuno saprà perché è stato creato in primo luogo).

  2. Potrebbe essere più complicato e dipenderà dalla situazione, ma direi che i consumatori degli eventi dovrebbero essere sempre pronti a ricevere eventi tardivi e fuori servizio e anche gli sviluppatori del BC difettoso non lo faranno sapere quali dipendenze ha quell'evento, quindi dovrebbero, a mio parere, pubblicare gli eventi in ritardo e il gioco è fatto (probabilmente aggiungerei l'invio di una notifica interna a tutti i team su questo fatto, per ogni evenienza).

risposta data 02.09.2018 - 17:33
fonte
1

Ci scusiamo per la mia risposta disinvolta. Event Sourcing (ES) è già in uso, a quanto pare.

Quindi alla tua prima domanda, come possono essere implementati nuovi servizi? La risposta è che dipende (come con tutte le cose) dal nuovo servizio. Quindi non ci sarà una risposta una tantum che si applicherà. L'utilizzo del servizio di fatturazione come esempio solleva un paio di domande. Innanzitutto, cosa fa il servizio di fatturazione? Funziona su un programma periodico? Ha bisogno di conoscere gli eventi degli altri BC in tempo reale? Supponiamo che tu abbia un servizio che prima era gratuito ma che ora sta per essere pagato o avere alcune funzionalità a pagamento. O forse vuoi solo iniziare l'utilizzo della contabilità internamente. In questo scenario, il servizio di fatturazione non ha davvero bisogno di sapere su ogni utente, hanno solo bisogno di sapere degli utenti che stanno facendo cose fatturabili dopo che il servizio di fatturazione è online. Quindi non è necessario pre-compilare il servizio. Senza saperne di più sul tuo esempio, qui non otterrai una buona risposta.

Alla seconda domanda, come possono essere corrette le incoerenze, fa implica l'uso di una sorta di ES ad un certo punto prima nel sistema. Se non hai affatto alcun ES allora hai perso gli eventi originali e devi, come suggerisci, portare in sincrono lo stato dei BC non originari con il BC originario.

Sei contro CAP. Nuovi eventi potrebbero entrare nel sistema quando lo stato viene convertito se si sceglie di mantenerlo online. Pertanto, se si desidera sincronizzare lo stato, è necessario decidere se interrompere o meno l'elaborazione degli eventi (disponibilità) o semplicemente disporre di dati incoerenti nei BC non originari.

L'ultima fonte di verità dipende dal tuo progetto. Non ne so abbastanza su ciò che stai effettivamente cercando di fare per fornire risposte più dettagliate. Siamo spiacenti.

    
risposta data 23.08.2018 - 01:54
fonte