Definizione delle dimensioni corrette di un microservizio Spesso senti qualcosa all'effetto di , "non troppo grande e non troppo piccolo" - e mentre questo è certamente corretto, non è molto utile in pratica. Se tuttavia si inizia da un modello di dominio progettato con attenzione, è molto più facile definire i microservizi.
Questo articolo usa un servizio di recapito tramite drone come esempio in esecuzione. Per altre informazioni sullo scenario e sull'implementazione di riferimento corrispondente, vedere qui.
Dal modello di dominio ai microservizi
Nell'articolo precedente è stato definito un set di contesti delimitati per un'applicazione di recapito tramite drone. È stato esaminato più attentamente uno di questi contesti delimitati, ovvero il contesto delimitato per il recapito, ed è stato identificato un set di entità, aggregazioni e servizi di dominio per tale contesto delimitato.
Ora è possibile passare dal modello di dominio alla progettazione dell'applicazione. Di seguito è riportato un approccio che è possibile usare per derivare i microservizi dal modello di dominio.
Iniziare con un contesto delimitato. In generale, la funzionalità di un microservizio non dovrebbe estendersi a più di un contesto delimitato. Un contesto delimitato segna per definizione il limite di un modello di dominio specifico. Se si nota che un microservizio combina modelli di dominio diversi, potrebbe essere necessario tornare indietro e perfezionare l'analisi del dominio.
Esaminare quindi le aggregazioni nel modello di dominio. Le aggregazioni sono spesso buoni candidati per i microservizi. Un'aggregazione progettata correttamente presenta molte delle caratteristiche di un microservizio ben progettato, ad esempio:
- Un'aggregazione deriva da requisiti aziendali piuttosto che da considerazioni di tipo tecnico, ad esempio l'accesso ai dati o la messaggistica.
- Un'aggregazione deve avere un'elevata coesione funzionale.
- Un'aggregazione è un limite di persistenza.
- Le aggregazioni devono essere a regime di controllo libero.
I servizi di dominio sono anche candidati ottimali per i microservizi. I servizi di dominio sono operazioni senza stato tra più aggregazioni. Un esempio tipico è un flusso di lavoro che coinvolge diversi microservizi. Si vedrà un esempio nell'applicazione di consegna con drone.
Tenere conto, infine, dei requisiti non funzionali. Esaminare alcuni fattori, ad esempio dimensioni del team, tipi di dati, tecnologie, requisiti di scalabilità, requisiti di disponibilità e requisiti di sicurezza. Questi fattori possono indurre a scomporre ulteriormente un microservizio in due o più servizi più piccoli oppure a effettuare l'operazione inversa, riunendo più microservizi in uno.
Dopo aver identificato i microservizi nell'applicazione, convalidare la progettazione in base ai criteri seguenti:
- Ogni servizio ha un'unica responsabilità.
- Non sono presenti chiamate frammentate tra servizi. Se la suddivisione delle funzioni in due servizi provoca un'eccessiva frammentazione dei servizi stessi, è possibile che queste funzioni debbano risiedere nello stesso servizio.
- Ogni servizio è sufficientemente piccolo da poter essere creato da un team di piccole dimensioni che opera in modo indipendente.
- Non sono presenti interdipendenze che richiedono la distribuzione di due o più servizi contemporaneamente. Deve essere sempre possibile distribuire un servizio senza ridistribuirne altri.
- I servizi non sono strettamente collegati e possono evolvere in modo indipendente.
- I limiti dei servizi non creeranno problemi di coerenza o integrità dei dati. In alcuni casi è importante mantenere la coerenza dei dati inserendo la funzionalità in un singolo microservizio. Ciò premesso, valutare se è realmente necessaria una coerenza di alto livello. Sono disponibili strategie per la coerenza finale in un sistema distribuito e i vantaggi della scomposizione dei servizi superano spesso la complessità di gestione della coerenza finale.
È soprattutto importante essere pragmatici e ricordare che la progettazione basata su dominio è un processo iterativo. In caso di dubbi, iniziare con microservizi con granularità grossolana. La suddivisione di un microservizio in due servizi più piccoli è più semplice del refactoring della funzionalità tra più microservizi esistenti.
Esempio: Definizione di microservizi per l'applicazione di recapito tramite drone
Tenere presente che il team di sviluppo ha identificato le quattro aggregazioni , ovvero Recapito, Pacchetto, Drone e Account, e due servizi di dominio, Utilità di pianificazione e Supervisore.
Recapito e Pacchetto sono candidati ovvi per i microservizi. L'Utilità di pianificazione e il Supervisore coordinano le attività eseguite da altri microservizi, quindi è opportuno implementare questi servizi di dominio come microservizi.
Drone e Account sono interessanti perché appartengono ad altri contesti delimitati. Una possibilità è che l'Utilità di pianificazione chiami direttamente i contesti delimitati Drone e Account. Un'altra opzione consiste nel creare i microservizi Drone e Account nel contesto delimitato per il recapito. Questi microservizi svolgerebbero una funzione di mediazione tra i contesti delimitati, esponendo API o schemi di dati più adatti al contesto per il recapito.
I dettagli dei contesti delimitati per il drone e l'account non rientrano nell'ambito di queste indicazioni, quindi sono stati creati servizi fittizi nell'implementazione di riferimento. Ecco alcuni fattori da prendere in considerazione in questa situazione:
Qual è il sovraccarico di rete in caso di chiamata diretta all'altro contesto delimitato?
Lo schema di dati dell'altro contesto delimitato è idoneo per questo contesto oppure è meglio uno schema personalizzato in funzione di questo contesto delimitato?
L'altro contesto delimitato è un sistema legacy? Se sì, è possibile creare un servizio che funga da livello antidanneggiamento per le attività di conversione tra il sistema legacy e l'applicazione moderna.
Qual è la struttura del team? È facile comunicare con il team responsabile dell'altro contesto delimitato? In caso contrario, la creazione di un servizio che funga da intermediario tra i due contesti consente di ridurre il costo delle comunicazioni tra i team.
Sinora non sono stati presi in considerazione requisiti funzionali. Pensando ai requisiti di velocità effettiva dell'applicazione, il team di sviluppo decide di creare un microservizio di inserimento separato responsabile dell'inserimento delle richieste dei client. Questo microservizio implementerà il livellamento del carico inserendo le richieste in ingresso in un buffer per l'elaborazione. L'Utilità di pianificazione leggerà le richieste presenti nel buffer ed eseguirà il flusso di lavoro.
I requisiti non funzionali inducono il team a creare un servizio aggiuntivo. Tutti i servizi sono stati sinora incentrati sulla pianificazione e il recapito di pacchetti in tempo reale. Il sistema deve tuttavia anche inserire la cronologia di ogni recapito nell'archiviazione a lungo termine per l'analisi dei dati. Il team considera l'ipotesi di affidare questa attività al servizio di recapito. I requisiti di archiviazione dei dati sono tuttavia sostanzialmente diversi per l'analisi cronologica rispetto alle operazioni in elaborazione (vedere Considerazioni sui dati). Il team decide quindi di creare un servizio cronologia di recapito distinto, che rimarrà in ascolto degli eventi DeliveryTracking del servizio di recapito e scriverà gli eventi nell'archiviazione a lungo termine.
Questa fase del progetto è illustrata nel diagramma seguente:
Scaricare un file di Visio di questa architettura.
Passaggi successivi
A questo punto, è necessario avere una chiara comprensione dello scopo e delle funzionalità di ogni microservizio nella progettazione. Ora è possibile progettare il sistema.