Un’architettura monolitica, come il nome suggerisce, è un modello di programmazione software in cui l’intero programma è costruito come un’unità singola e indivisibile. Ogni componente del programma, incluso il livello di accesso ai dati, la logica di business e l’interfaccia utente, è distribuito nella stessa soluzione e le funzionalità dei diversi processi sono integrate insieme.
Al contrario, i microservizi sono un’architettura che struttura l’applicazione in diversi programmi separati che possono essere distribuiti in modo indipendente, con più componenti che comunicano tra loro in rete, tipicamente gestendo flussi di dati per mezzo di endpoint REST.
Fino a qualche anno fa, lo sviluppo software tipicamente prediligeva l’architettura monolitica per una maggiore semplicità di design e programmazione. La crescente necessità di gestire grandi quantità di dati e di utenti ha però mostrato i limiti di scalabilità di questo modello software, e molto big player si sono orientati alle soluzioni basate sui microservizi. Le differenze tra le due architetture hanno infatti un profondo impatto su tutto il ciclo di vita dell’applicazione, a partire dallo sviluppo fino alla sua scalabilità e agli aspetti legati alla sicurezza.
Sviluppo e manutenzione
Lo sviluppo di un programma monolitico sembra inizialmente più semplice rispetto all’orchestrazione di una suite di microservizi, ma più il progetto si evolve, più la scelta dell’architettura monolitica mostra i propri limiti.
Nel caso occorra sviluppare una nuova funzionalità, questo non può essere fatto in modo del tutto indipendente, ma dovendo essere ogni sviluppo incorporato in un unico gruppo di sorgenti, si rischia di avere impatti anche su altre parti del codice.
Una volta concluso lo sviluppo, sono poi richiesti la ricompilazione e il rilascio di una nuova versione dell’intera soluzione, con i disagi che ne conseguono a livello di disponibilità per gli utenti. Anche i deploy di patch per aggiornare componenti non core richiedono la messa off-line completa del servizio.
Sviluppare su una soluzione basata su microservizi, invece, permette di aggirare questi limiti: un aggiornamento non deve essere installato sull’intera soluzione, ma viene eseguito in modo mirato solo sul componente target. L’architettura a microservizi semplifica anche la gestione dei ticket, permettendo alle risorse del personale di supporto di specializzarsi solo su alcuni processi specifici invece di dover acquisire dimestichezza con l’intero corpo della soluzione.
Ottimizzazione e scalabilità
Un altro vantaggio dei microservizi è che questa architettura permette a diversi linguaggi e tecnologie di accesso ai dati di convivere all’interno della medesima soluzione. Nulla vieta che un microservizio sia scritto in Python e acceda a dei dati su Mongo DB e un altro sia realizzato in C# ed esegua operazioni CRUD su un database SQL. Questa molteplicità di tecnologie non è implementabile su un’architettura monolitica, dove la scelta di utilizzare per alcune funzioni un linguaggio più performante richiederebbe la riscrittura dell’intera soluzione nel nuovo linguaggio. Nella soluzione a microservizi, se si presenta la necessità, è possibile eseguire il refactoring di un componente decidendo di utilizzare una tecnologia estranea agli altri servizi.
Essendo indipendenti tra loro, i microservizi offrono una migliore scalabilità e permettono un bilanciamento ottimale delle risorse impiegate: è possibile infatti allocare RAM e CPU (virtuali o meno) a ogni componente calibrando i consumi in base alle effettive necessità delle singole funzionalità. Inoltre, diventa più semplice individuare e gestire eventuali colli di bottiglia rispetto alla soluzione unica, in cui tutte le funzionalità accedono al medesimo pool di risorse.
Sicurezza
Apparentemente la soluzione monolitica sembra più semplice da gestire da un punto di vista della sicurezza poiché i microservizi presentano molteplici superfici d’attacco. Il suo tallone d’Achille è che, se anche una sola funzionalità viene penetrata, l’intera soluzione viene compromessa.
Al contrario, se un microservizio viene violato da un hacker, può essere isolato dagli altri componenti pur mantenendo online una parte delle altre funzionalità. L’isolamento dei componenti offerto dai microservizi ha fatto sì che molte realtà con situazioni critiche di cyber security (come le banche, ad esempio) abbiano basato su questo modello la propria infrastruttura.
Migrazione da un’architettura monolitica ai microservizi
Trasformare un software legacy in microservizi richiede un attento lavoro di analisi iniziale. Occorre eseguire un inventario dei flussi di dati interni in modo da poter individuare i componenti potenzialmente isolabili da ripubblicare sotto forma di API.
Questa attività risulterà facilitata se è stato impiegato almeno un pattern design a oggetti, in modo da poter partire da classi e interfacce ben definite. Avendo accesso ai sorgenti, è possibile impiegare anche l’ausilio di intelligenze artificiali specializzate nella scrittura di codice, come ad esempio Claude Haiku, per trasformare le logiche legacy in dndpoint fruibili per mezzo di chiamate REST.
Una delle difficoltà maggiori di un refactoring di questo tipo è la gestione dell’accesso ai dati: ogni microservizio deve infatti poter avere un proprio accesso alla base dati, e questo potrebbe comportare la riscrittura delle viste per gestire la separazione degli ambiti causata dalla spaccatura della logica originaria in diversi componenti.