2015-04-05 14 views
20

Considerate i seguenti servizi di micro per un progetto di negozio on-line:
utenti del servizio mantiene i dati dell'account sugli utenti del negozio (tra cui nome, cognome, indirizzo e-mail, ecc ')Microservices Architettura: i dati di servizio trasversale condivisione

Il servizio acquisti tiene traccia dei dettagli sugli acquisti dell'utente.

Ogni servizio fornisce un'interfaccia utente per la visualizzazione e la gestione delle relative entità. La pagina di indice del servizio acquisti elenca gli acquisti. Ogni articolo di acquisto dovrebbe avere i seguenti campi:
id, nome completo dell'acquirente, titolo dell'oggetto acquistato e prezzo.
Inoltre, come parte della pagina indice, mi piacerebbe avere una casella di ricerca per consentire al gestore del negozio di cercare acquisti acquistando il nome utente.

Non mi è chiaro come recuperare i dati che il Servizio acquisti non contiene, ad esempio: il nome completo dell'utente. Il problema peggiora quando si cerca di fare cose più complicate come acquisti di ricerca acquistando il nome utente.

Ho immaginato di poter ovviare a questo problema sincronizzando gli utenti tra i due servizi trasmettendo una sorta di evento sulla creazione dell'utente (e salvando solo le proprietà utente rilevanti sul Servizio acquisti). Questo è lontano dall'ideale nella mia prospettiva. Come gestisci questo quando hai milioni di utenti? creeresti milioni di record in ogni servizio che consuma i dati degli utenti?

Un'altra opzione ovvia è l'esposizione di un'API al servizio utenti che riporta i dettagli dell'utente in base a determinati ID. Ciò significa che ogni pagina caricata nel Servizio acquisti, dovrò effettuare una chiamata al Servizio utenti per ottenere i nomi utente corretti. Non ideale, ma posso conviverci.

Che ne pensi di implementare una ricerca di acquisto in base al nome utente? Bene, posso sempre esporre un altro endpoint dell'API al termine del servizio utenti che riceve il termine della query, eseguire una ricerca di testo su nomi utente nel servizio utenti e quindi restituire tutti i dettagli dell'utente che corrispondono ai criteri. Nel Servizio acquisti, associare gli ID pertinenti ai nomi corretti e mostrarli nella pagina. Anche questo approccio non è l'ideale.

Mi manca qualcosa? C'è un altro approccio per implementare quanto sopra? Forse il fatto che sto affrontando questo problema è una sorta di odore di codice? mi piacerebbe sentire altre soluzioni.

+0

Sono un po 'confuso dalla domanda. L'applicazione di fine font dovrebbe essere separata dai servizi. Dovresti essere in grado di apportare modifiche alle applicazioni front end senza modificare un servizio. Per la schermata di acquisto, è necessario chiamare il servizio di acquisto e il servizio utenti per ottenere i dati per lo schermo. In alternativa, una API separata potrebbe essere messa di fronte ai servizi che chiameranno entrambi i servizi e quindi restituiranno i dati allo schermo. Dai uno sguardo al diagramma [qui] (http://martinfowler.com/articles/microservices.html#DecentralizedDataManagement) che mostra come dovrebbe funzionare. –

+0

Ecco il modello dell'API: http://microservices.io/patterns/apigateway.html –

risposta

3

È assolutamente necessario conservare i dati appropriati in diversi database, si chiama Polyglot Persistence. Sì, desideri conservare separatamente i dati degli utenti e i dati sugli acquisti e utilizzare la coda dei messaggi per la sincronizzazione. Milioni di utenti mi sembrano a posto, è scalabile, non è un problema di progettazione ;-)

In caso di ricerca, probabilmente si desidera cercare più di un semplice nome utente, giusto? Pertanto, se si utilizza la coda messaggi per aggiornare i dati tra servizi, è anche possibile instradare facilmente questi dati su ElasticSearch, ad esempio. E dal punto di vista di ElasticSearch non importa quale campo indicizzare - nome utente o titolo del prodotto.

13

Questa sembra essere una domanda molto comune e centrale quando si passa ai microservizi. Vorrei che ci fosse una buona risposta per questo :-)

Circa lo schema suggerito già menzionato qui, utilizzerei il termine Data Denormalization piuttosto che Polyglot Persistence, in quanto non deve necessariamente essere in diverse tecnologie di persistenza. Il punto è che ogni servizio gestisce i propri dati. E sì, hai la duplicazione dei dati e di solito hai bisogno di un qualche tipo di bus eventi per condividere i dati tra i vari servizi.

C'è un'altra opzione, che è una sorta di presa sul primo: effettuare la ricerca per sé come servizio separato.

Quindi nel tuo esempio, hai il servizio Utente per la gestione degli utenti. I servizi Acquisti gestisce gli acquisti. Ognuno gestisce i propri dati e solo i dati di cui ha bisogno (quindi, ad esempio, il servizio Acquisti non ha realmente bisogno del nome utente, solo dell'ID). E tu hai un terzo servizio - il servizio di ricerca - che consuma dati prodotti da altri servizi e crea una "vista" di ricerca dai dati combinati.

1

Di solito uso entrambi gli approcci. A volte ho un altro servizio che si trova in cima su x altri servizi e combina i dati. Non mi piace molto questo approccio perché causa dipendenza e accoppiamento tra i servizi. Quindi, in generale, nei miei ultimi progetti abbiamo cercato di attenerci alla persistenza poliglotta.

Inoltre, se hai bisogno di avere x richieste http per combinare i dati in un qualche tipo di servizio middleware, questo ti porterà ad una maggiore latenza. Cerchiamo sempre di ridurre la quantità di richieste per un'attività e gestire tutto ciò che è possibile attraverso le code asincrone. (in particolare sincronizzazione dei dati)

Problemi correlati