Microservizi o monolite? Come scegliere l'architettura giusta per il tuo prodotto
Non esiste un'architettura universalmente superiore. La scelta tra monolite e microservizi dipende dal contesto, dal team e dagli obiettivi. Ecco come ragionare sulla decisione senza cadere nelle mode del momento.
Architettura SoftwareMicroserviziMonoliteEngineeringC'è una domanda che ritorna puntuale in ogni progetto software che supera una certa taglia: «Dobbiamo passare ai microservizi?». A volte la risposta è sì — ma più spesso di quanto si creda, la risposta corretta è «no, almeno non adesso» o «dipende da cosa stai cercando di risolvere». L'architettura a microservizi è diventata lo standard aspirazionale di riferimento negli ultimi dieci anni, al punto che scegliere il monolite è sembrato, per un certo periodo, ammettere un ritardo culturale. Quella narrazione era sbagliata, e il settore sta lentamente correggendo la rotta.
In MAST affrontiamo questa scelta regolarmente, per noi e per i clienti. Quello che segue non è un'opinione su cosa sia «meglio in assoluto» — è un framework per ragionare la decisione con la testa dritta.
Cosa significa davvero «monolite»
Il termine ha acquisito una connotazione negativa che non si merita. Un monolite, nella sua forma essenziale, è un'applicazione deployata come unità singola. Non è sinonimo di codice disorganizzato, accoppiamento caotico o impossibilità di scalare. È semplicemente un modello di deployment — e come tale, ha caratteristiche precise, né buone né cattive in sé.
Un monolite ben strutturato può avere:
- Moduli interni chiaramente separati con confini di dominio rispettati
- Transazioni atomiche tra diverse parti del sistema senza overhead di rete
- Un solo processo da deployare, monitorare e debuggare
- Chiamate in-process invece di chiamate HTTP/gRPC, con latenza zero e nessuna serializzazione
Il problema non è il monolite: è il monolite mal progettato, quello dove tutto dipende da tutto e ogni modifica richiede di capire l'intero sistema. Ma quella degenerazione può colpire anche i microservizi — anzi, nei microservizi è più difficile da vedere e più costosa da risolvere.
Cosa aggiungono (davvero) i microservizi
I microservizi spostano il confine di deployment: invece di un'unica unità, il sistema è composto da tanti servizi indipendenti, ognuno responsabile di una parte del dominio. Questo porta vantaggi reali — ma solo in condizioni specifiche.
Deploy indipendente. Se il team di pagamenti può rilasciare senza aspettare il team di catalogo, i cicli di deploy si accorciano e il rischio si isola. Questo conta quando hai team multipli che lavorano su domini diversi con ritmi diversi.
Scalabilità selettiva. Puoi scalare il servizio di ricerca senza scalare il servizio di notifiche. Ha senso quando i carichi sono davvero asimmetrici e il costo dell'infrastruttura è rilevante.
Tecnologie diverse per dominio diverso. Il motore di raccomandazioni può girare su Python/ML mentre il backend transazionale gira su Java. Utile quando i requisiti tecnici di un sottodominio differiscono davvero dagli altri.
Isolamento dei guasti. Un crash nel servizio di notifiche non abbatte il flusso di checkout. La resilienza aumenta — a patto di gestire correttamente i fallimenti parziali.
Questi vantaggi sono reali. Ma hanno un prezzo, e il prezzo è più alto di quanto spesso si stimi prima di costruire.
Il costo nascosto dei microservizi
Quando un team adotta i microservizi senza aver raggiunto la maturità operativa necessaria, scopre che ogni vantaggio porta con sé un problema nuovo.
Complessità distribuita. Ogni chiamata tra servizi è una chiamata di rete: può fallire, essere lenta, andare in timeout. Devi gestire retry, circuit breaker, idempotenza. Problemi che in un monolite non esistono o si risolvono con una transazione diventano sfide di ingegneria distributa.
Overhead operativo. Più servizi significano più pipeline CI/CD, più container, più configurazioni, più ambienti da mantenere. Se non hai un'infrastruttura matura (Kubernetes, service mesh, observability diffusa), stai solo aggiungendo lavoro senza raccogliere i benefici.
Debug e tracing. Tracciare una richiesta che attraversa sei servizi è incomparabilmente più difficile che tracciarne una in un singolo processo. Senza distributed tracing e log centralizzati sei cieco.
Consistenza dei dati. In un monolite, una transazione è atomica. In un sistema distribuito, la consistenza immediata è spesso impossibile: bisogna progettare per consistenza eventuale, saga, o compensazioni. Questo richiede un salto concettuale che non tutti i team sono pronti a fare.
Latenza aggiunta. Le chiamate in-process sono ordini di grandezza più veloci delle chiamate HTTP. Se il tuo sistema fa molte operazioni che richiedono dati da domini diversi, la latenza aggregata cresce — e l'utente la sente.
I microservizi spostano la complessità dall'applicazione all'infrastruttura e alla rete. Quella complessità non sparisce: si trasforma.
Come ragionare la scelta
La domanda giusta non è «microservizi o monolite?» ma «quali sono i vincoli e gli obiettivi che devo soddisfare?». Tre assi di valutazione sono utili.
1. La dimensione del team
Il confine tra microservizi ha senso quando rispecchia il confine tra team. La Legge di Conway dice che un'organizzazione tende a produrre architetture che riflettono la sua struttura di comunicazione — ed è vera. Se hai due sviluppatori, una architettura a venti servizi non accelera il lavoro: lo frammentare. Se hai dieci team autonomi che lavorano su domini separati, un monolite shared diventa un collo di bottiglia umano prima ancora che tecnico.
Regola pratica: inizia a prendere in considerazione i microservizi quando hai almeno due team con domini chiaramente separati e necessità di deploy indipendenti.
2. La fase del prodotto
Un prodotto in fase esplorativa cambia continuamente: le API, i confini di dominio, le responsabilità dei moduli evolvono ogni sprint. Definire i confini dei servizi troppo presto è quasi sempre sbagliato — paghi il costo del refactoring distribuito ogni volta che il dominio cambia. Il monolite permette refactoring rapidi e a basso costo.
Un prodotto maturo, con domini stabili e team dedicati, è invece il candidato ideale per estrarre gradualmente dei servizi dai moduli più stressati.
Regola pratica: costruisci un monolite modulare finché il dominio non si stabilizza. Estrai i servizi quando hai prove che servono, non prima.
3. I requisiti operativi
Stai già gestendo monitoring, alerting, tracing distribuito, infrastruttura container? Hai un team di platform o di SRE? Se sì, l'overhead operativo dei microservizi è già in parte pagato. Se no, dovrai costruirlo da zero mentre costruisci anche il prodotto — e il rischio di fallire su entrambi i fronti è alto.
La terza via: il monolite modulare
Non è necessario scegliere tra monolite big ball of mud e microservizi piena distribuzione. La posizione più difendibile per la maggior parte dei prodotti in crescita è il monolite modulare: un'applicazione deployata come unità singola, ma con confini di dominio rigidamente applicati nel codice.
I moduli comunicano tra loro attraverso interfacce esplicite, non accedono direttamente al database dell'altro, e i confini di responsabilità sono chiari. Quando — e se — un modulo dovrà diventare un servizio, il lavoro di estrazione è molto più semplice perché i confini sono già definiti.
È l'approccio che Sam Newman (autore di Building Microservices) raccomanda come punto di partenza, e che Martin Fowler chiama Strangler Fig Pattern quando applicato a sistemi legacy: non spezzare tutto in una volta, ma isolare e estrarre gradualmente, un pezzo alla volta, dove c'è un vantaggio concreto.
Come lo affrontiamo in MAST
Quando lavoriamo con un cliente su decisioni architetturali, il punto di partenza non è «quale pattern è più moderno» ma «quale problema stai cercando di risolvere». Spesso la risposta è che il problema reale non è l'architettura: è un dominio mal modellato, team organizzati in modo incoerente rispetto al sistema, o un debito tecnico localizzato che si può affrontare senza ridisegnare tutto.
Quando i microservizi hanno senso, li adottiamo — ma sempre con una roadmap operativa chiara: osservabilità prima, automazione del deploy prima, definizione dei confini prima. Senza quell'infrastruttura, il beneficio non arriva.
La scelta dell'architettura è una decisione tecnica con implicazioni organizzative, operative ed economiche. Va presa con dati, non con hype.
Stai valutando un'evoluzione architetturale del tuo sistema? Parliamone — affrontiamo questi percorsi con un'analisi del contesto prima di qualsiasi raccomandazione.
Vuoi parlarne con noi?
Parliamone →