Pattern: Microservice Architecture
Context
Stai sviluppando un’applicazione aziendale lato server. Deve supportare una varietà di client diversi, inclusi browser desktop, browser mobili e applicazioni mobili native. L’applicazione potrebbe anche esporre un’API per l’utilizzo da parte di terze parti. Potrebbe anche integrarsi con altre applicazioni tramite servizi Web o un broker di messaggi. L’applicazione gestisce le richieste (richieste e messaggi HTTP) eseguendo la logica di business; accedere a un database; scambio di messaggi con altri sistemi; e restituendo una risposta HTML / JSON / XML. Esistono componenti logici corrispondenti a diverse aree funzionali dell’applicazione.
Problema
Qual è l’architettura di distribuzione dell’applicazione?
Forze
- Esiste un team di sviluppatori che lavora sull’applicazione
- I nuovi membri del team devono diventare rapidamente produttivi
- L’applicazione deve essere di facile comprensione e modificare
- Desideri fare pratica con la distribuzione continua dell’applicazione
- Devi eseguire più istanze dell’applicazione su più macchine per soddisfare i requisiti di scalabilità e disponibilità
- Desideri trarre vantaggio dalle tecnologie emergenti (framework, linguaggi di programmazione, ecc.)
Soluzione
Definisci un’architettura che strutturi l’applicazione come un insieme di elementi debolmente accoppiati, servizi di collaborazione.Questo approccio corrisponde all’asse Y dello Scale Cube.Ogni servizio è:
- Altamente manutenibile e testabile – consente ra pid e frequente sviluppo e implementazione
- Abbinato liberamente ad altri servizi – consente a un team di lavorare in modo indipendente la maggior parte del tempo sui propri servizi senza essere influenzato da modifiche ad altri servizi e senza influire su altri servizi
- Distribuibile in modo indipendente: consente a un team di implementare il proprio servizio senza doversi coordinare con altri team
- In grado di essere sviluppato da un piccolo team – essenziale per un’elevata produttività evitando l’alto responsabile della comunicazione di grandi team
I servizi comunicano utilizzando protocolli sincroni come HTTP / REST o protocolli asincroni come AMQP. I servizi possono essere sviluppati e distribuiti indipendentemente l’uno dall’altro.Ogni servizio ha il proprio database per essere disaccoppiati da altri servizi.La coerenza dei dati tra i servizi viene mantenuta utilizzando il modello Saga
Per saperne di più sulla natura di un servizio, leggi questo articolo.
Esempi
Applicazione di e-commerce fittizia su
Immaginiamo che tu stia costruendo un’applicazione di e-commerce che prenda gli ordini dai clienti, verifichi l’inventario e il credito disponibile e li spedisca. L’applicazione è composta da diversi componenti tra cui StoreFrontUI, che implementa l’interfaccia utente , insieme ad alcuni servizi di backend per il controllo del credito, il mantenimento dell’inventario e la spedizione degli ordini. L’applicazione è costituita da una serie di servizi.
Mostrami il codice
Vedi le applicazioni di esempio sviluppate da Chris Richardson. Questi esempi su Github illustrano vari aspetti dell’architettura dei microservizi.
Contesto risultante
Vantaggi
Questa soluzione presenta una serie di vantaggi:
- Consente la distribuzione e l’implementazione continua di applicazioni grandi e complesse.
- Migliore manutenibilità: ogni servizio è relativamente piccolo ed è quindi più facile da capire e modificare
- Migliore testabilità: i servizi sono più piccoli e più veloci da testare
- Migliore implementabilità – servizi può essere distribuito in modo indipendente
- Ti consente di organizzare lo sforzo di sviluppo attorno a più team autonomi. Ogni squadra (cosiddetta due pizze) possiede ed è responsabile di uno o più servizi. Ogni team può sviluppare, testare, distribuire e ridimensionare i propri servizi indipendentemente da tutti gli altri team.
- Ogni microservizio è relativamente piccolo:
- Più facile per un sviluppatore per capire
- L’IDE è più veloce rendendo gli sviluppatori più produttivi
- L’applicazione si avvia più velocemente, il che rende gli sviluppatori più produttivi e accelera le distribuzioni
- Isolamento dei guasti migliorato. Ad esempio, se si verifica una perdita di memoria in un servizio, solo quel servizio sarà interessato. Gli altri servizi continueranno a gestire le richieste. In confronto, un componente che si comporta in modo anomalo di un’architettura monolitica può arrestare l’intero sistema.
- Elimina qualsiasi impegno a lungo termine per uno stack tecnologico. Quando si sviluppa un nuovo servizio è possibile scegliere un nuovo stack tecnologico. Allo stesso modo, quando si apportano modifiche importanti a un servizio esistente è possibile riscriverlo utilizzando un nuovo stack tecnologico.
Svantaggi
Questa soluzione presenta una serie di svantaggi:
- Gli sviluppatori devono affrontare la complessità aggiuntiva della creazione di un sistema distribuito:
- Gli sviluppatori devono implementare il meccanismo di comunicazione tra i servizi e gestire gli errori parziali
- L’implementazione di richieste che si estendono su più servizi è più difficile
- Testare le interazioni tra i servizi è più difficile
- L’implementazione di richieste che abbracciano più servizi richiede un attento coordinamento tra i team
- Gli strumenti per sviluppatori / IDE sono orientati alla creazione di applicazioni monolitiche e non forniscono supporto esplicito per lo sviluppo di applicazioni distribuite.
- Complessità di distribuzione. Nella produzione, esiste anche la complessità operativa della distribuzione e della gestione di un sistema composto da molti servizi diversi.
- Aumento del consumo di memoria. L’architettura del microservizio sostituisce N istanze di applicazioni monolitiche con istanze dei servizi NxM. Se ogni servizio viene eseguito nella propria JVM (o equivalente), che di solito è necessario per isolare le istanze, si verifica un sovraccarico di M volte il numero di runtime JVM. Inoltre, se ogni servizio viene eseguito sulla propria VM (ad es. Istanza EC2), come nel caso di Netflix, l’overhead è ancora più elevato.
Problemi
Ci sono molti problemi che devi affrontare.
Quando utilizzare l’architettura dei microservizi?
Una sfida nell’utilizzo di questo approccio è decidere quando ha senso utilizzarlo. Quando si sviluppa la prima versione di un’applicazione, spesso non si hanno i problemi che questo approccio risolve.Inoltre, l’utilizzo di un’architettura elaborata e distribuita rallenterà lo sviluppo.Questo può essere un grosso problema per le startup la cui sfida più grande è spesso come far evolvere rapidamente il modello di business e l’accompagnamento L’utilizzo delle suddivisioni sull’asse Y potrebbe rendere molto più difficile l’iterazione rapida. In seguito, tuttavia, quando la sfida è come ridimensionare ed è necessario utilizzare la decomposizione funzionale, le dipendenze aggrovigliate potrebbero rendere difficile scomporre la tua applicazione monolitica in un insieme di servizi.
Come scomporre l’applicazione in servizi?
Un’altra sfida è decidere come suddividere il sistema in microservizi. Questa è un’arte, ma ci sono una serie di strategie che possono aiutare:
- Decomponi per capacità aziendale e definisci i servizi corrispondenti alle capacità aziendali.
- Decomponi per sottodominio di progettazione basato sul dominio.
- Decomponi per verbo o caso d’uso e definisci i servizi responsabili di azioni particolari . per esempio. un
Shipping Service
responsabile della spedizione di ordini completi. - Decomponi per nomi o risorse definendo un servizio che è responsabile di tutte le operazioni su entità / risorse di un dato genere. per esempio. un
Account Service
responsabile della gestione degli account utente.
Idealmente, ogni servizio dovrebbe avere solo un piccolo insieme di responsabilità. (Zio) Bob Martin parla della progettazione di classi utilizzando il principio di responsabilità unica (SRP) .L’SRP definisce una responsabilità di una classe come motivo per cambiare e afferma che una classe dovrebbe avere solo una ragione per cambiare.Ha senso applicare l’SRP alla progettazione del servizio
Un’altra analogia che aiuta con la progettazione di servizi è la progettazione di utilità Unix. Unix fornisce un gran numero di utilità come grep, cat e find. Ogni utilità fa esattamente una cosa, spesso eccezionalmente bene, ed è concepito per essere combinato con altre utilità utilizzando uno script di shell per eseguire attività complesse.
Come mantenere la coerenza dei dati?
Per garantire un accoppiamento libero, ogni servizio ha il proprio Il mantenimento della coerenza dei dati tra i servizi è una sfida perché le transazioni di commit / distribuzione a 2 fasi non lo sono un’opzione per molte applicazioni.Un’applicazione deve invece utilizzare il pattern Saga.Un servizio pubblica un evento quando i suoi dati cambiano.Altri servizi consumano quell’evento e aggiornano i loro dati.Ci sono diversi modi per aggiornare in modo affidabile i dati e pubblicare eventi tra cui Event Sourcing e Transaction Log Tailing.
Come implementare le query?
Un’altra sfida è implementare le query che devono recuperare i dati di proprietà di più servizi.
- L’API Modelli di composizione e segregazione della responsabilità della query di comando (CQRS).
Esistono molti modelli relativi al modello di microservizi. L’architettura monolitica è un’alternativa all’architettura del microservizio. Gli altri modelli risolvono i problemi che incontrerai quando applichi l’architettura del microservizio.
- Modelli di decomposizione
- Decomponi per capacità aziendale
- Decomponi per sottodominio
- Il modello Database per servizio descrive come ciascuno il servizio dispone di un proprio database per garantire un accoppiamento libero.
- Il pattern API Gateway definisce il modo in cui i client accedono ai servizi in un’architettura di microservizi.
- I pattern di individuazione lato client e rilevamento lato server vengono utilizzati per instradare le richieste di un client a un istanza di servizio disponibile in un’architettura di microservizi.
- I pattern Messaging e Remote Procedure Invocation sono due modi diversi in cui i servizi possono comunicare.
- I pattern Single Service per Host e Multiple Services per Host sono due diverse strategie di implementazione.
- Schemi di interesse trasversale: modello di chassis del microservizio e configurazione esternalizzata
- Schemi di test: test dei componenti del servizio e test del contratto di integrazione del servizio
- Circuito Breaker
- Token di accesso
- Modelli di osservabilità:
- Aggregazione dei log
- Metriche dell’applicazione
- Log di controllo
- Traccia distribuita
- Tracciamento delle eccezioni
- API di controllo dello stato
- Registra distribuzioni e modifiche
- Pattern dell’interfaccia utente:
- Composizione del frammento di pagina lato server
- Composizione dell’interfaccia utente lato client
Usi noti
La maggior parte dei siti web su larga scala, inclusi Netflix, Amazon ed eBay, si sono evoluti da un’architettura monolitica a un’architettura di microservizi.
Netflix, che è un servizio di streaming video molto popolare che è responsabile fino al 30% del traffico Internet, ha un’architettura orientata ai servizi su larga scala Gestisce oltre un miliardo di chiamate al giorno alla loro API di streaming video da oltre 800 diversi tipi di dispositivi Ogni API chiama i fan a una media di sei chiamate ai servizi di backend.
Amazon.com aveva originariamente un’architettura a due livelli. Per scalare, migrò a un’architettura orientata ai servizi composta da centinaia di servizi di backend. Diverse applicazioni chiamano questi servizi, comprese le applicazioni che implementano il sito Web Amazon.com e l’API del servizio Web. L’applicazione del sito Web Amazon.com chiama 100-150 servizi per ottenere l’estensione dati utilizzati per costruire una pagina web.
Anche il sito di aste ebay.com si è evoluto da un’architettura monolitica a un’architettura orientata ai servizi. Il livello dell’applicazione è costituito da più applicazioni indipendenti. Ogni applicazione implementa la logica di business per un’area di funzione specifica come l’acquisto o la vendita. Ogni applicazione utilizza le suddivisioni dell’asse X e alcune applicazioni come la ricerca utilizzano le suddivisioni dell’asse Z.Ebay.com applica anche una combinazione di ridimensionamento in stile X, Y e Z al livello database.
Esistono numerosi altri esempi di aziende che utilizzano l’architettura dei microservizi.
Chris Richardson ha esempi di applicazioni basate sui microservizi.
Vedi anche
Vedi la mia nota introduttiva di Code Freeze 2018, che fornisce una buona introduzione all’architettura dei microservizi.