Architetture monolitiche e di microservizi
Fabrikam ha integrato il nuovo servizio di drone nell'applicazione esistente, ma si è visto che questa soluzione non è un piano a lungo termine valido per l'applicazione. Il sistema esistente è un'architettura monolitica, ma cosa significa esattamente?
Che cos'è un'architettura monolitica?
Un'architettura monolitica è un'architettura in cui tutti i componenti di un'applicazione si trovano in una singola unità. Questa unità è in genere vincolata all'interno di una singola istanza di runtime dell'applicazione. Le applicazioni tradizionali sono spesso costituite da un'interfaccia Web, un livello servizi e un livello dati. In un'architettura monolitica i vari livelli sono combinati in un'istanza dell'applicazione.
Le architetture monolitiche sono spesso soluzioni adatte per le applicazioni di piccole dimensioni, ma possono diventare scomode quando l'applicazione si espande. Un'applicazione in origine di piccole dimensioni può diventare rapidamente un sistema complesso difficile da ridimensionare, difficile da usare per la distribuzione e difficile da innovare.
Tutti i servizi sono contenuti all'interno di una singola unità. Questa soluzione presenta dei problemi non appena l'azienda, e di conseguenza il carico del sistema, cresce. Questi sono alcuni dei problemi:
- Difficoltà nel ridimensionare i servizi in modo indipendente.
- Complessità dello sviluppo e della gestione delle distribuzioni con la crescita della codebase, con un rallentamento dei rilasci di nuove versioni e dell'implementazione delle nuove funzionalità.
- L'architettura è limitata a un singolo stack tecnologico, che a sua volta limita l'innovazione in nuovi SDK e piattaforme,
- Aumento della complessità degli aggiornamenti dello schema dei dati.
Queste sfide possono essere affrontate scegliendo architetture alternative, ad esempio un'architettura di microservizi.
Che cos'è un'architettura di microservizi?
Un'architettura di microservizi è costituita da servizi di piccole dimensioni, indipendenti e ad accoppiamento debole. Ogni servizio può essere distribuito e ridimensionato in modo indipendente.
Le dimensioni di un microservizio sono sufficientemente piccole da consentirne la scrittura e la gestione da parte di un unico piccolo team di sviluppatori. Poiché i servizi possono essere distribuiti in modo indipendente, un team può aggiornare un servizio esistente senza ricompilare e ridistribuire l'intera applicazione.
Ogni servizio è in genere responsabile della gestione dei propri dati. La struttura dei dati è isolata, in modo che gli aggiornamenti o le modifiche dello schema non dipendano da altri servizi. Le richieste di dati vengono in genere gestite con le API e consentono di usare un modello di accesso ben definito e coerente. I dettagli di implementazione interna sono nascosti ai consumer.
Poiché ogni servizio è indipendente, si possono usare diversi stack tecnologici, framework e SDK. È comune vedere servizi che si basano sulle chiamate REST per la comunicazione da servizio a servizio usando API ben definite anziché RPC o altri metodi di comunicazione personalizzati.
Le architetture di microservizi sono indipendenti dalla tecnologia, ma spesso per la loro implementazione vengono usati contenitori o tecnologie serverless. Vengono spesso usate tecniche di distribuzione continua e integrazione continua (CI/CD) per aumentare la velocità e la qualità delle attività di sviluppo.
Vantaggi di un'architettura di microservizi
Perché scegliere un'architettura di microservizi? Un'architettura di microservizi offre diversi vantaggi importanti:
- Agilità
- Piccola quantità di codice e piccoli team
- Combinazione di tecnologie
- Resilienza
- Scalabilità
- Isolamento dei dati
Agilità
Poiché i microservizi vengono distribuiti in modo indipendente, è più facile gestire le correzioni di bug e i rilasci delle funzionalità. È possibile aggiornare un servizio senza ridistribuire l'intera applicazione ed eseguire il rollback di un aggiornamento in caso di errore. In molte applicazioni tradizionali un bug rilevato in una parte dell'applicazione può bloccare l'intero processo di rilascio. Di conseguenza, per le nuove funzionalità può essere necessario attendere l'integrazione, il test e la pubblicazione di una correzione di bug.
Piccola quantità di codice e piccoli team
Un microservizio deve essere sufficientemente piccolo da consentire a un singolo un team responsabile di una funzionalità di crearlo, testarlo e distribuirlo. Le codebase di piccole dimensioni sono più facili da comprendere. In un'applicazione monolitica di grandi dimensioni le dipendenze del codice tendono ad aggrovigliarsi nel tempo. L'aggiunta di una nuova funzionalità richiede interventi sul codice in molte posizioni. Un'architettura di microservizi riduce al minimo le dipendenze non condividendo codice o archivi dati. In questo modo è più facile aggiungere nuove funzionalità.
I team di piccole dimensioni inoltre lavorano in modo più flessibile. Secondo la "regola delle due pizze", un team deve essere sufficientemente piccolo da potersi nutrire con due pizze. Ovviamente non si tratta di una metrica esatta, visto che dipende dall'appetito del team. Il concetto, tuttavia, è che i gruppi di grandi dimensioni tendono a essere meno produttivi, perché la comunicazione è più lenta, la gestione è più complessa e la flessibilità diminuisce.
Combinazione di tecnologie
I team possono scegliere la tecnologia che meglio si adatta ai servizi in uso. Possono usare una combinazione di stack tecnologici in base alle esigenze. Ogni team può sviluppare le tecnologie che supportano il servizio in modo indipendente. Grazie a questa indipendenza, i servizi possono usare diversi linguaggi di sviluppo, servizi cloud, SDK e altro ancora. I team possono scegliere le opzioni migliori per il servizio, riducendo al minimo qualsiasi effetto esterno sui consumer del servizio.
Resilienza
Se un singolo microservizio smette di essere disponibile, non si interrompe l'intera applicazione, a condizione che i microservizi upstream siano progettati per gestire correttamente gli errori (ad esempio, implementando l'interruzione del circuito). Il vantaggio per gli utenti o i consumer del servizio è il fatto che l'applicazione rimane sempre disponibile.
Scalabilità
Un'architettura di microservizi consente la scalabilità di ogni microservizio indipendentemente dagli altri microservizi. È possibile ampliare i sottosistemi che richiedono più risorse, senza ridimensionare l'intera applicazione. Questa soluzione migliora le prestazioni complessive dell'applicazione. Consente inoltre di ridurre al minimo i costi. È possibile aggiungere altre risorse solo ai servizi che le richiedono, anziché ridimensionare l'intera applicazione.
Isolamento dei dati
Con un'architettura di microservizi è più semplice aggiornare lo schema dei dati, perché è interessato solo un singolo microservizio. In un'applicazione monolitica gli aggiornamenti dello schema possono diventare complessi. Diverse parti dell'applicazione possono interessare tutte gli stessi dati, rendendo rischiosa qualsiasi modifica apportata allo schema. Con un'architettura di microservizi, è possibile aggiornare uno schema ma mantenere intatta la superficie dell'API. I consumer del servizio hanno quindi la stessa esperienza indipendentemente dall'architettura dei dati sottostante.
Potenziali sfide di un'architettura di microservizi
Esistono molti vantaggi per un'architettura di microservizi, ma non è una soluzione universale. Un'architettura di microservizi ha un proprio set di problemi:
- Complessità
- Sviluppo e test
- Mancanza di governance
- Congestione e latenza di rete
- Integrità dei dati
- Gestione
- Controllo delle versioni
- Competenze
Complessità
Un'applicazione di microservizi ha più parti mobili rispetto all'applicazione monolitica equivalente. Ogni servizio è più semplice, ma l'intero sistema nella sua totalità è più complesso. Con gli strumenti di individuazione dei servizi, orchestrazione e automazione può essere necessario gestire più parti nell'applicazione globale.
Sviluppo e test
La scrittura di un servizio di piccole dimensioni che si basa su altri servizi dipendenti richiede un approccio diverso rispetto alla scrittura di una tradizionale applicazione monolitica o a più livelli. Gli strumenti esistenti non sempre sono progettati per gestire le dipendenze dei servizi. Effettuare il refactoring tra i limiti dei servizi può essere difficile. Può risultare complesso anche testare le dipendenze dei servizi, in particolare quando l'applicazione si evolve rapidamente.
Mancanza di governance
L'approccio decentralizzato alla creazione di microservizi presenta alcuni vantaggi, ma può anche causare problemi. Potrebbero esserci così tanti linguaggi e framework diversi che l'applicazione diventa difficile da gestire. Può essere utile applicare alcuni standard a livello di progetto, senza limitare eccessivamente la flessibilità dei team. L'esigenza di adottare standard uniformi vale in particolare per le funzionalità trasversali come la registrazione e le metriche.
Congestione e latenza di rete
L'uso di molti servizi granulari di dimensioni ridotte può comportare una maggiore comunicazione tra i servizi. Se la catena delle dipendenze dei servizi diventa troppo lunga, ad esempio il servizio A chiama il servizio B, che a sua volta chiama il servizio C e così via, la latenza aggiuntiva per queste chiamate di rete può diventare un problema. Progettare attentamente le API. Evitare API eccessivamente "frammentate", considerare i formati di serializzazione e cercare posizioni appropriate in cui usare modelli di comunicazione asincrona.
Integrità dei dati
Ogni microservizio è responsabile della persistenza dei propri dati, quindi la coerenza dei dati può risultare un problema. Implementare la coerenza finale dove possibile. Potrebbero anche venire generati dati duplicati e l'architettura dei dati può diventare complessa. Questa situazione può comportare un aumento dei costi di archiviazione dei dati non elaborati e dei costi dei servizi della piattaforma dati, a causa della duplicazione di dati e servizi.
Gestione
Una corretta implementazione dei microservizi richiede una conoscenza avanzata dei concetti DevOps. La registrazione correlata tra i servizi può risultare complessa. In genere, la registrazione deve correlare più chiamate ai servizi per una singola operazione utente.
Controllo delle versioni
Gli aggiornamenti di un servizio non devono interrompere i servizi che dipendono da esso. È possibile che più servizi vengano aggiornati in un determinato momento. Senza un'attenta progettazione si potrebbero verificare problemi di compatibilità con le versioni precedenti o successive. I servizi che ritardano l'adozione di nuove versioni API possono comportare un aumento delle risorse e delle attività di manutenzione necessarie per le API precedenti.
Competenze
I microservizi sono sistemi altamente distribuiti. Questi sistemi distribuiti spesso richiedono un set di competenze diverso per eseguire correttamente lo sviluppo, la gestione e la manutenzione. Valutare attentamente se il team ha le competenze e l'esperienza necessarie. Lasciare ai team il tempo necessario per acquisire le competenze necessarie e metterli nelle condizioni di pianificare i progetti.
Quando è consigliabile scegliere un'architettura di microservizi?
Considerando tutte queste informazioni di base, in quali situazioni è appropriata un'architettura di microservizi?
- Applicazioni di grandi dimensioni che richiedono una velocità di rilascio elevata.
- Applicazioni complesse che devono essere altamente scalabili.
- Applicazioni con domini complessi o molti sottodomini.
- Un'organizzazione costituita da team di sviluppo di piccole dimensioni.