Gestione dell'accesso al database per MicroServices

3

Al momento disponiamo di un flusso di lavoro in cui dividiamo un Monolito in microservizi e abbiamo discusso su come accedere e mantenere i dati.

Per darti un'idea di come viene configurata la maggior parte delle nostre app, abbiamo un'app costruita rigorosamente per l'interfaccia utente, un'API Web con cui si parla e quindi un'altra API Web che, con l'API, gestisce l'accesso gestionale al database.

Anche se sembra decisamente interessante avere un'API Web che usiamo per gestire l'accesso al database, dobbiamo ancora costruire endpoint specifici per ogni app e, per la maggior parte, l'API Web della nostra interfaccia utente parla solo agisce come un proxy.

Inoltre, non esiste un modello di progettazione reale, usiamo semplicemente la nostra Web API come proxy, o configuriamo più endpoint nell'API del livello dati e consumiamo tutti quelli per creare i nostri DTO?

Questo è un progetto C # e usiamo tipicamente Entity Framework, quindi per me sembra che usare un approccio Database First per generare le nostre Entità nella nostra API Web abbia molto più senso. In questo modo non gestiamo le migrazioni in più progetti.

Sembra troppo tardi nel gioco per separare il nostro database in più database, il che è qualcosa che preferirei.

    
posta The Pax Bisonica 15.02.2018 - 18:44
fonte

1 risposta

6

In generale, il processo di migrazione di un monolite a un'architettura di microservizi comporta l'estrazione accurata di parti dal monolite in modo che possano vivere come applicazioni autonome. Ad esempio, consideriamo un sistema di prenotazioni alberghiere. Disponi di un sottosistema noleggio per allocare sale, un sottosistema del profilo per mantenere i dati sui clienti, un sottosistema di fatturazione e così via 1 . Questo è il nostro punto di partenza.

Il monolite molto probabilmente si è evoluto in modo organico per mesi o anni e tutti i sottosistemi non sono disaccoppiati come si vorrebbe. Da una prospettiva di microservizio, questo è male. Il nostro primo passo sarà quello di prendere uno di questi sottosistemi (di solito il meno rischioso) e di ri-architettarlo all'interno del monolite in modo che sia completamente disaccoppiato. Nel nostro esempio, questo potrebbe essere il sottosistema del profilo.

L'accesso ai dati dei clienti è diffuso ovunque nel nostro codice. Il nostro primo compito è isolare questo sottosistema. Sposteremo il codice in una libreria separata che esporrà un'interfaccia attraverso la quale gli altri sottosistemi richiederanno dati sui clienti. Questo è molto importante: nessun altro sottosistema può chiedere direttamente al database i dati del cliente. Loro hanno per chiedere al servizio queste informazioni.

Una volta che questo passaggio è terminato 2 , il sottosistema è pronto per essere spostato sul proprio servizio per vivere da solo. In quel che resta del monolite, ora, invece di utilizzare la libreria per accedere ai dati dei clienti, chiameremo il nuovo servizio profili autonomo 3 . Abbiamo il nostro primo microservizio 4 .

Abbiamo realizzato due cose molto importanti:

  1. Il microservizio ha alta coesione . Tutto ciò che riguarda i dati dei clienti è ora isolato nel proprio microservizio. Tutte le modifiche al modo in cui i dati dei clienti vengono mantenuti e al modo in cui le regole di business dei clienti vengono applicate hanno come ambito un singolo servizio;
  2. C'è basso accoppiamento tra il nuovo microservice e il resto del codice. Quando cambiamo il modo in cui persistono i dati dei clienti, il sottosistema di noleggio non è completamente interessato. Quale è una buona cosa: non dovrebbe preoccuparsi di questo, si preoccupa solo di affitti.

Tornando al tuo caso d'uso, mi sembra che tu stia tornando indietro. Costruendo "microservices" di fronte al monolite alle chiamate proxy, hai creato due problemi importanti.

  1. Hai ridotto la coesione del tuo sistema. Le nuove funzionalità molto probabilmente richiederanno modifiche nel servizio proxy per modificare l'API, quindi le modifiche al monolite per supportare questa nuova API.
  2. Hai aumentato l'accoppiamento tra i due servizi, perché ora devi modificarli entrambi per ogni funzione.

Non stai ottenendo i benefici di un'architettura di microservizio, ma hai comunque aumentato la complessità del sistema nel suo complesso. Il tuo monolite è ancora solo un grande, è ancora costoso eseguire tutte le tue suite di test e coinvolgere il QA per ogni correzione di bug o funzionalità e non puoi fare progressi quanto vuoi.

1. Nella progettazione basata su domini, questi sottosistemi sarebbero certamente contesti limitati.
2. Anche se è possibile estrarre subito il sottosistema in un servizio separato, è probabilmente una buona idea aspettare che la sua interfaccia pubblica si stabilizzi attraverso alcune funzionalità. Una volta estratto in un nuovo microservizio, potrebbe essere costoso correggere gli errori a causa del posizionamento non corretto dei limiti.
3. Ciò significa che anche se si può effettivamente utilizzare la stessa istanza di un DBMS per tutti i servizi, il database del servizio A non deve essere accoppiato al database del servizio B. Ad esempio, se si aveva una tabella customer e una tabella rental e aveva una chiave esterna customer.id in rental , dovrai cancellare questa chiave esterna e perdere questa integrità referenziale applicata dal DBMS. Dovrai garantire la coerenza in un altro modo. È il prezzo da pagare in un'architettura di microservizi.
4. Ovviamente, ho omesso molta complessità dell'infrastruttura da questa risposta. Fare microservizi non è un frutto basso in sospensione: assicurati che sia effettivamente appropriato per il tuo caso d'uso!

    
risposta data 16.02.2018 - 23:18
fonte

Leggi altre domande sui tag