L’architettura monolitica è stata per molti anni il vero punto di riferimento dello sviluppo software. L’emergere di nuove metodologie e l’incalzante diffusione del cloud ha profondamente mutato gli scenari, favorendo la diffusione del modello a microservizi e delle cosiddette applicazioni moderne, almeno nel senso cronologico del termine, prima di entrare nel merito della logica e delle tecnologie che le caratterizzano.

Tuttavia, anche se la sua popolarità è data in qualche modo in calo, il software monolitico non è affatto morto e in molti frangenti presenta ancora dei vantaggi decisivi per la sua implementazione. Vediamo cosa si intende per architettura monolitica, cosa comporta per lo sviluppo delle applicazioni e quali sono i contesti che lo rendono tuttora preferibile rispetto ad altre soluzioni, in primis l’architettura a microservizi.

Cos’è l’architettura monolitica

L’architettura monolitica rappresenta il tradizionale modello per lo sviluppo di un software ed è caratterizzata dal fatto di contenere tutte le funzioni all’interno di un unico blocco. Da questo particolare deriva anche il suo appellativo, metaforicamente ispirato dalla figura del monolite, storicamente riconoscibile in un blocco di pietra, solido per natura e scarsamente incline alla suddivisione in più parti.

Un software definito dall’architettura monolitica è logicamente autonomo, in quanto i suoi componenti sono fortemente accoppiati e interdipendenti. In altri termini, i componenti di un software monolitico non possono essere separati o riutilizzati senza procedere con l’aggiornamento integrale dell’intera applicazione. Una modifica puntuale comporta pertanto la ricompilazione dell’intero codice per creare un nuovo eseguibile. Non è possibile disaccoppiare une singola funzione e procedere soltanto al suo aggiornamento.

La logica di un’architettura monolitica, come vedremo, si colloca agli antipodi rispetto alla logica modulare che caratterizza ad esempio l’architettura a microservizi. Detto così, potrebbe sembrare che un’architettura monolitica presenti soltanto una serie di svantaggi o sia considerabile alla stregua di un dinosauro in un tempo che non è più il suo. In realtà, oltre ad avere caratterizzato per decenni il modello di riferimento per lo sviluppo software, il software monolitico rimane un modello di riferimento valido in moltissime circostanze.

Vediamo pertanto quali sono i principali pro e contro dell’architettura monolitica, ai fini di prefigurare gli ambiti di utilizzo ideali per questo modello di sviluppo, prima di vedere nello specifico le principali differenze rispetto all’architettura a microservizi.

I vantaggi

Il software monolitico è caratterizzato da una serie di vantaggi intrinseci nella sua architettura informatica.

Test e Debug

Il fatto di contenere tutti i componenti all’interno di un’unica applicazione fa si che le architetture monolitiche si prestino in maniera più rapida ed efficiente alle fasi di test e alle operazioni di debug del software, in quanto tutto rimane sotto lo stretto controllo dello sviluppatore. La forte dipendenza tra i componenti stessi rende evidente in maniera immediata qualsiasi problema di funzionamento, dal momento che si manifesta in maniera immediata nel funzionamento dell’applicazione.

Design

Se le metodologie di sviluppo di moderna concezione, come DevOps e Agile, risultano particolarmente efficienti nel caso di applicazioni vaste, complesse e caratterizzate da un ciclo di vita lungo ed articolato, che non possono prescindere da una logica modulare, l’architettura monolitica continua a rappresentare la metodologia di design più semplice ed immediata per concepire un’applicazione capace di eseguire simultaneamente più funzioni.

Il monolitico, per la sua stessa natura, non presenta rischi di “sovra-architettura”, in quanto tutto il necessario per far funzionare il software è contenuto all’interno dell’applicazione stessa, senza dover ricorrere ad una complessa architettura di componenti tra loro disaccoppiati, che possono certamente risultare più comodi nelle fasi di sviluppo, ma vanno successivamente messi in comunicazione tra loro per consentire il completo funzionamento del software.

Nel caso dell’architettura monolitica questo sforzo non è necessario. Per tali ragioni, lo sviluppo da zero di un’applicazione monolitica, specie se comparata con altre metodologie, risulta piuttosto rapida, in quanto il suo design non prevede la complessità di comunicazione tra i componenti chiamati a dialogare con l’interfaccia principale.

Performance

La struttura monolitica del software riduce ai minimi termini la comunicazione interna tra i componenti, rendendo l’esecuzione più rapida, soprattutto al primo avvio, quando ancora non è stato effettuato un caching dell’applicazione nella memoria di sistema: caching che comporta a sua volta un’ulteriore complessità da gestire a livello di sviluppo.

Quando si prevede di sviluppare un software che usato simultaneamente da persone che non necessitano di un gran numero di funzioni, o un software rimarrà confinato all’interno di una singola linea di business, l’architettura monolitica può generare evidenti vantaggi a livello di performance, che si configurano in maniera sinergica con gli altri aspetti positivi sin qui rilevati.

Sicurezza

Disporre di un’applicazione concentrata in un unico blocco agevola notevolmente il controllo delle autorizzazioni sugli accessi e sulla possibilità di modificare nei modi più svariati gli elementi che la compongono. Per applicazioni di simile dimensioni e complessità, la superficie di attacco di un’architettura monolitica si presenta piuttosto ridotta, se confrontata con le architetture basate su componenti disaccoppiati (SOA, microservizi, ecc.). Un ulteriore vantaggio è costituito dall’utilizzo di un database centralizzato, particolare che rende a sua volta più semplici le procedure relative alla protezione dei dati, tra cui il backup e ripristino in caso di incidenti.

Gli svantaggi

Un design di vecchia generazione, come quello dell’architettura monolitica mostra evidenti limiti quando si presenta la necessità di sviluppare e mantenere applicazioni moderne, in particolare per la difficoltà nello sfruttare molte possibilità tecnologiche offerte dal cloud computing. Nel caso dell’architettura monolitica dobbiamo infatti riscontrare evidenti limiti sul fronte dell’aggiornabilità, della flessibilità e della manutenzione.

Aggiornabilità dispendiosa

L’aggiornamento di un software monolitico comporta necessariamente l’aggiornamento dell’intera applicazione e l’installazione attraverso un nuovo eseguibile, a cui corrisponde una nuova versione del software stesso. Si tratta di un aspetto poco economico quando si avrebbe ad esempio la necessità di risolvere un semplice bug in una funzione. Non sarebbe sufficiente aggiornare il relativo componente, ma andrebbe rilasciata una nuova versione dell’intero applicativo.

L’architettura monolitica non si presta pertanto alle logiche della distribuzione continua CI/CD (Continous integration / Continuous Delivery) tipica di metodologie di sviluppo moderne come DevOps o Agile o in generale ad applicazioni che richiedono frequenti aggiornamenti, in quanto eccessivamente dispendiosa in termini di risorse.

Flessibilità ridotta

L’architettura monolitica prevede l’impiego di un unico linguaggio di programmazione per lo sviluppo dell’intera applicazione. Tale caratteristica risulta scarsamente strategica nei confronti della grande varietà tecnologica attualmente disponibile, verso cui avrebbe tutto il senso approcciarsi scegliendo la tecnologia più indicata per lo sviluppo di ogni singola funzione presente nel software.

La pipeline di sviluppo di un software monolitico prevede inoltre che tutti gli sviluppatori conoscano il funzionamento complessivo dell’applicazioni, anche se la loro attività è concentrata soltanto sul lavoro relativo ad alcuni componenti, per il fatto che questi sono strettamente accoppiati ed interdipendenti. Nel caso di applicazioni di media ed elevata complessità, questa lacuna in termini di agilità si riflette in maniera evidente nell’implementazione dei team di sviluppo ed in generale comporta oneri in termini di competenze e tempi di realizzazione tutt’altro che trascurabili.

Manutenzione scomoda

Nel caso di applicazioni per cui si prevede un lungo ciclo di vita, il modello monolitico può presentare alcuni limiti anche sul fronte della manutenzione, dal momento che il suo sviluppo appare fortemente legato all’attività dei programmatori e delle tecnologie coinvolte per dare forma alla versione originale del software.

Tale aspetto può presentare evidenti criticità qualora per aggiornare un software monolitico fosse necessario coinvolgere competenze e linguaggi di programmazione specifici. Un caso frequente è dato dalla circostanza in cui i programmatori originali non lavorano più per l’azienda che ha sviluppato il software o quando si è costretti a continuare con una tecnologia datata, quando sul mercato nel frattempo sono state rese disponibili soluzioni più performanti.

Monolitica vs Microservizi: le differenze

Dopo aver descritto gli aspetti peculiari dell’architettura monolitica, con particolare attenzione per gli svantaggi, risulterà immediato comprendere le logiche alla base dell’architettura a microservizi, che nasce proprio per superare i limiti del monolite di fronte all’esigenza di nuove metodologie di sviluppo, come DevOps e Agile.

Contrariamente a quanto previsto dal modello monolitico, l’architettura a microservizi si basa sulla decomposizione del monolite grazie al disaccoppiamento dei suoi componenti, che possono essere quindi trattati in maniera indipendente, come delle applicazioni autonome che comunicano tra loro attraverso opportune API.

I singoli componenti del software possono essere gestiti da team di sviluppo diversi, utilizzando linguaggi di programmazione differenti, in quanto non c’è una dipendenza tecnologica tra le varie funzioni che concorrono alla composizione di un’applicazione. Tale logica è molto utilizzata nell’ambito delle web application e di quelle che in generale vengono definite applicazioni moderne, come quelle basate sul modello di distribuzione Software-as-a-Service (SaaS), che aggiornano continuamente il software (CI/CD) senza costringere l’utente finale ad installare una nuova versione, come sarebbe inevitabile nel caso di una versione monolitica.

Nel caso dell’architettura a microservizi è quindi possibile aggiornare soltanto i componenti del software che lo necessitano, senza dover necessariamente effettuare un deploy dell’intera applicazione. Nel caso di progetti ben pianificati, i componenti sono aggiornati praticamente in tempo reale, senza comportare evidenti downtime nei confronti dell’utente finale, che il più delle volte non si accorge praticamente di nulla, pur avendo sempre a disposizione la versione più aggiornata del software che utilizza.

Il ridotto livello di accoppiamento dei microservizi rende inoltre favorevole il loro riutilizzo nell’ambito di applicazioni del tutto differenti, che richiedono la stessa tipologia di funzione.

Per supportare lo sviluppo dei microservizi i provider dei principali ecosistemi cloud mettono a disposizione tecnologie specifiche, come nel caso dei container, dei veri e propri ambienti di runtime virtualizzati a livello del sistema operativo, che mettono a disposizione tutti gli elementi necessari per eseguire le varie applicazioni, in maniera tra loro totalmente indipendente, garantendo loro un elevato livello di portabilità.

Va comunque precisato che il cloud non esclude approcci di sviluppo di natura tradizionale. Anzi, anche il software monolitico potrebbe essere tranquillamente containerizzato, collocando l’intera applicazione in un unico container, laddove risiedono tutti i componenti necessari al suo funzionamento, ma è evidente che tecnologie di questo genere siano state concepite per poter creare ed orchestrare situazioni architetturalmente molto più complesse del monolite, che rimane pertanto associato ad un modello di sviluppo tradizionale, tipico delle applicazioni legacy, o di soluzioni moderne, ma funzionalmente semplici da implementare e gestire.

Le differenze tra architettura monolitica e microservizi in un esempio pratico: le applicazioni e-commerce

Per comprendere in maniera semplice ed intuitiva le differenze che intercorrono tra l’architettura monolitica e i microservizi è sufficiente una descrizione sommaria di una delle applicazioni web al momento più diffuse, ossia quelle utilizzate in ambito e-commerce.

Nella sua configurazione più elementare, un’applicazione e-commerce potrebbe essere costituita dai seguenti componenti: interfaccia front-end, integrazione sito web aziendale, configuratore di prodotto, catalogo prodotti, carrello, sistema di pagamento, piattaforma di back-end, sistema di generazione degli ordini, oltre a tutte le integrazioni con i sistemi aziendali (CRM, ERP, ecc.) relativi ai canali di comunicazione e di relazione con i clienti. Sembrano tante, ma sarebbero molte di più. In questa descrizione ci siamo limitati al minimo indispensabile.

Tale contesto, come facilmente prevedibile, si sposa alla perfezione con un’architettura dove i vari microservizi corrispondono esattamente ad ognuna delle funzioni citate. Tali componenti vengono aggiornati in modo piuttosto variabile. L’interfaccia e il catalogo prodotti potrebbero ad esempio prevedere una serie di deploy piuttosto frequenti, mentre il carrello potrebbe rimanere invariato anche per lunghi periodi, così come il sistema di generazione degli ordini. I prodotti variano infatti in maniera molto più rapida rispetto alle pipeline di fabbricazione e distribuzione logistica necessari per farli arrivare con successo nelle mani dei clienti.

Se utilizzassimo un’architettura monolitica, ad ogni aggiornamento significativo del catalogo prodotti, o per risolvere un semplice bug del configuratore, dovremmo rilasciare nuovamente l’intera applicazione. Fortunatamente un’architettura a microservizi ci consente di agire in maniera puntuale, lavorando sui componenti interessati, senza coinvolgere ciò che non è necessariamente oggetto di modifica.

Le funzioni previste da un’applicazione e-commerce molto spesso non vengono rilasciate da un unico soggetto, perché le tecnologie necessarie sono rese disponibili da vari fornitori, che agiscono in maniera del tutto indipendente tra loro. Gli UX designer che si occupano dell’interfaccia non sono infatti tenuti a conoscere i dettagli relativi agli asset del catalogo prodotti o al sistema di gestione degli ordini implementato nel back-end. Non sarebbe loro di alcuna utilità e finirebbe soltanto per fargli perdere tempo e distrarli dalle loro mansioni.

Questa considerazione vale per la maggior parte dei soggetti coinvolti nello sviluppo dei vari componenti. Per rendere ancora più chiaro questo concetto, ci basti pensare che in molti casi si provvede direttamente ad integrare alcune soluzioni standardizzate, come nel caso dei sistemi di pagamento online, i cui circuiti (Paypal, carte di credito, ecc.) predispongono una serie di estensioni da implementare in continuità con la funzione di check-out prevista dal carrello. È chi gestisce lo sviluppo dell’applicazione principale a doversi adeguare a questi standard, non il contrario, come sarebbe lecito attendersi a livello gerarchico.

A gestire questa complessità, montando i vari pezzi del puzzle, ci pensano infatti i project manager, mentre i singoli team da loro coordinati possono occuparsi di quanto gli compete nella maniera più agile ed efficiente possibile, senza preoccuparsi del lavoro degli altri team, se non strettamente necessario.

Se dovessimo sviluppare un’applicazione e-commerce con un modello monolitico, rischieremmo semplicemente di impazzire, in quanto presenta praticamente in toto le caratteristiche più ostiche per la sua logica e la sua architettura. Non avrebbe semplicemente alcun senso.

Quale architettura scegliere?

Molto spesso si parte a sviluppare una nuova applicazione sul modello a microservizi, anche per via del fatto che la maggior parte degli sviluppatori è ormai abituata a lavorare in team, adottando metodologie come DevOps o Agile. Oltre che sul fronte organizzaivo, tale scelta prospetta indubbi vantaggi anche sul fronte tecnologico, grazie alla possibilità di avvalersi delle piattaforme in cloud, ma molto spesso si configura come la più classica delle armi a doppio taglio.

I team meno esperti nel valutare le conseguenze in fase di analisi potrebbero lasciarsi trascinare dall’hype e dalle tendenze di mercato, finendo per sottovalutare che la complessità della gestione di un progetto basato sull’architettura a microservizi non sempre giustifica l’impegno necessario per sostenere effettivamente un progetto. Questo vale soprattutto se l’applicazione in questione non presenta un numero di funzioni elevato, non prevede aggiornamenti frequenti e un ciclo di vita particolarmente esteso. In tali casi, molto spesso è tuttora più conveniente adottare un’architettura monolitica.

In definitiva, l’architettura monolitica e l’architettura a microservizi si completano molto bene, quindi non avrebbe alcun senso agire per partito preso, diventando dei fan dell’uno o dell’altro approccio, quando si ha la possibilità di utilizzare la metodologia di sviluppo e le tecnologie più efficaci per dare forma a qualsiasi applicazione.

Come sempre, per risolvere un problema sono possibili molte soluzioni, ma orientarsi in questa varietà tecnologica non è affatto semplice se non si dispone delle necessarie competenze e di un sufficiente livello di esperienza, che deriva dal quotidiano rapporto con le aziende e da decine di casi risolti con successo.

Specie quando si presenta la necessità di sviluppare un’applicazione dall’alto valore strategico è decisamente auspicabile avvalersi della consulenza di un ISV o di un system integrator capace di analizzare e definire con puntualità le esigenze di business, trovando di conseguenza la soluzione più efficace dal punto di vista tecnologico, a partire dalla sua fattibilità a livello economico.