Da Monolite a Microservizi: Una Guida Pratica per CTO di Startup in Crescita
Il tuo monolite ti ha portato fin qui. Ha permesso a un team piccolo di consegnare velocemente, fare deploy con una singola pipeline e debuggare con uno stack trace invece di tracciare log attraverso cinque servizi diversi. Ha funzionato. E se hai seguito i principi di un monolite modulare ben progettato, ti ha dato una base solida.
Ma ora qualcosa e cambiato. Hai tre team che lavorano sullo stesso repository e i conflitti di merge sono costanti. Il modulo di elaborazione pagamenti ha bisogno di scalare diversamente da quello delle notifiche. Un deploy che dovrebbe richiedere dieci minuti ne richiede sessanta perche bisogna coordinarsi tra i team. Un bug nel modulo di reporting blocca il rilascio di una funzionalita di fatturazione pronta da una settimana.
Questi sono segnali reali. E la risposta non e "riscriviamo tutto in microservizi questo trimestre". La risposta e evolvere gradualmente.
Quando e davvero il momento di migrare
Non migri perche i microservizi vanno di moda. Migri perche il monolite e diventato un collo di bottiglia per il tuo business. Ecco i segnali concreti:
Piu team si pestano i piedi a vicenda. Due team toccano lo stesso codice, le PR si bloccano reciprocamente, e ogni merge richiede coordinamento che consuma piu tempo dello sviluppo stesso. La legge di Conway inizia a farsi sentire: la tua architettura deve riflettere la tua organizzazione.
Esigenze di scaling divergenti. La tua API di ricerca deve scalare orizzontalmente con il traffico degli utenti, ma il servizio di elaborazione file ha bisogno di macchine con piu RAM e CPU. Scali tutto il monolite per soddisfare il componente piu esigente, pagando infrastruttura di cui il resto non ha bisogno.
Deploy troppo lunghi e rischiosi. Una modifica di tre righe richiede il deploy dell'intera applicazione. La pipeline di CI impiega 45 minuti. E ogni deploy e un evento che genera ansia perche qualsiasi parte del sistema puo rompersi.
Un guasto rompe tutto. Un memory leak nel modulo di reporting manda giu l'API clienti, la dashboard di amministrazione e il sistema di fatturazione. Non c'e isolamento dei guasti.
Se riconosci due o piu di questi segnali, e il momento di pianificare la migrazione. Se ne vedi solo uno, probabilmente puoi risolvere il problema con una migliore modularizzazione interna.
Lo Strangler Fig Pattern: non riscrivere, estrai
La metafora viene dal fico strangolatore, una pianta che cresce attorno a un albero esistente fino a sostituirlo completamente. Il tuo monolite e l'albero. I nuovi servizi sono il fico. E la chiave e che l'albero resta vivo mentre il fico cresce.
Non riscrivi il monolite. Estrai servizi uno a uno, gradualmente, mentre il monolite continua a funzionare in produzione. Ogni estrazione e un passo piccolo e controllato. Se qualcosa va storto, il monolite e ancora li come fallback.
Passo 1: Identifica i confini
Prima di estrarre qualsiasi cosa, ti serve una mappa chiara dei moduli del tuo monolite e delle loro dipendenze. Se hai progettato un monolite modulare con bounded context ben definiti, questa parte e piu semplice. Se no, e il momento di farlo.
Cerca le cuciture naturali: moduli che comunicano con il resto attraverso interfacce chiare, che hanno il proprio modello dati, che rappresentano un dominio di business distinto. In termini di Domain-Driven Design, stai cercando bounded context.
Disegna il grafo delle dipendenze. Identifica quali moduli dipendono da quali. Quelli con meno dipendenze in entrata e in uscita sono i candidati piu facili per l'estrazione.
Passo 2: Estrai il modulo che causa piu dolore
Non iniziare dal modulo piu facile ne dal piu difficile. Inizia da quello che causa piu dolore. Normalmente e quello che soddisfa una o piu di queste condizioni:
- Scala diversamente dal resto del sistema.
- Cambia con alta frequenza e genera conflitti con altri team.
- Ha requisiti tecnologici diversi (serve GPU, un database diverso, un runtime specifico).
- I suoi guasti impattano in modo sproporzionato sul resto del sistema.
Estrai quel modulo come servizio indipendente. Fai il deploy separatamente. Dagli la sua pipeline CI/CD. Assegnagli un team che ne sia responsabile.
Passo 3: Metti un API gateway o reverse proxy davanti
Qui avviene la magia dello Strangler Fig. Posizioni un API gateway (Kong, NGINX, AWS API Gateway, Traefik) davanti a tutto il tuo sistema. Le richieste che prima andavano direttamente al monolite ora passano dal gateway.
Il gateway decide: questa richiesta va al nuovo servizio, quest'altra continua ad andare al monolite. Puoi fare il cambio gradualmente -- inizia redirigendo il 5% del traffico al nuovo servizio, monitora, e sali progressivamente al 100%.
Se il nuovo servizio fallisce, il gateway puo redirigere di nuovo al monolite. Migrazione senza rischio esistenziale.
Passo 4: Sposta i dati (la parte piu difficile)
Qui e dove la maggior parte delle migrazioni si complica. Finche il tuo nuovo servizio continua a leggere e scrivere nello stesso database del monolite, non hai un vero microservizio -- hai un monolite distribuito, che e il peggio di entrambi i mondi.
L'obiettivo e che ogni servizio abbia il proprio database. Il percorso per arrivarci:
- Dual write. Il nuovo servizio scrive nel proprio database E in quello del monolite durante un periodo di transizione. Verifichi che i dati siano consistenti.
- Sincronizzazione a eventi. Introduci un sistema di eventi (Kafka, RabbitMQ, SNS/SQS) per mantenere sincronizzati i dati tra il servizio e il monolite.
- Cutover. Quando hai fiducia che il nuovo servizio e la source of truth, elimini la scrittura nel database del monolite. Gli altri moduli che necessitano di quei dati li ottengono tramite l'API del nuovo servizio o consumano i suoi eventi.
Accetta che ci sara un periodo di eventual consistency. Non provare a mantenere transazioni ACID tra servizi -- quella strada porta a distributed transaction e two-phase commit, che sono fragili e lenti.
Passo 5: Ripeti
Estrai il servizio successivo. E quello dopo. Ogni estrazione dovrebbe richiedere settimane, non mesi. Se un'estrazione ti sta richiedendo tre mesi, probabilmente stai estraendo un modulo troppo grande o le dipendenze non erano cosi chiare come pensavi.
Con ogni estrazione, il monolite diventa piu piccolo e piu gestibile. Alla fine, cio che resta e un servizio in piu -- oppure si decompone naturalmente negli ultimi due o tre servizi.
L'infrastruttura necessaria
I microservizi non sono solo codice in repository separati. Hanno bisogno di infrastruttura di supporto che non esisteva nel tuo mondo monolitico:
Service discovery. I servizi devono trovarsi tra loro. Consul, DNS interno di Kubernetes, o il service discovery del tuo cloud provider.
Logging centralizzato. Con dieci servizi, non puoi fare SSH su ogni macchina per leggere i log. Ti servono ELK Stack, Datadog, Grafana Loki -- un posto dove tutti i log convergano.
Distributed tracing. Una request dell'utente puo toccare cinque servizi. Senza tracing (Jaeger, Zipkin, Datadog APM), debuggare un errore e tirare a indovinare in quale servizio si e originato. Implementa OpenTelemetry dal primo servizio.
CI/CD per servizio. Ogni servizio ha la propria pipeline. Modifichi il servizio pagamenti, si deploya solo il servizio pagamenti. GitHub Actions, GitLab CI o lo strumento che usi, ma indipendente per servizio.
Monitoraggio e alerting. Health check, metriche di latenza, tassi di errore, saturazione delle risorse -- per servizio. Se non riesci a vedere lo stato di ogni servizio in un dashboard, stai navigando alla cieca.
Cosa non fare
Non estrarre tutto insieme. La tentazione di "facciamo la migrazione completa in un trimestre" e forte. Resisti. Ogni estrazione e un rischio controllato. Dieci estrazioni simultanee sono caos.
Non creare nano-servizi. Un servizio con un solo endpoint e 200 righe di codice non dovrebbe essere un servizio. Ha tutto l'overhead operativo di un microservizio senza nessun beneficio. Un servizio deve rappresentare un dominio di business con senso proprio.
Non iniziare dal modulo piu accoppiato. Se il modulo utenti e intrecciato con tutto il sistema, e il peggior candidato per la prima estrazione. Inizia con qualcosa che abbia meno dipendenze.
Non dimenticare il monitoraggio. Ogni servizio che estrai senza un monitoraggio adeguato e una scatola nera in produzione. Prima l'osservabilita, poi l'estrazione.
Struttura dei team: ogni servizio ha bisogno di un owner
Un microservizio senza un team responsabile e un servizio orfano. E i servizi orfani accumulano debito tecnico a velocita allarmante perche nessuno si sente responsabile di mantenerli.
Ogni servizio ha bisogno di un team che ne sia chiaramente responsabile. Quel team decide il suo roadmap, gestisce i suoi deploy, risponde quando fallisce alle tre di notte. Non deve essere un team dedicato esclusivamente a quel servizio -- un team puo essere owner di due o tre servizi correlati. Ma la proprieta deve essere esplicita.
Questo e esattamente cio che descrive la legge di Conway invertita: progetti la tua architettura perche rifletta la struttura di team che vuoi avere. Se vuoi team autonomi che consegnino in modo indipendente, ti servono servizi che possano essere sviluppati e deployati in modo indipendente.
La migrazione e un processo, non un progetto
La migrazione da monolite a microservizi non ha una data di fine in un diagramma di Gantt. E un processo continuo che evolve con la tua organizzazione. Estrai servizi quando il dolore lo giustifica, non perche c'e un piano che dice che tocca.
In Conectia, lavoriamo con startup europee che sono esattamente a questo punto: il monolite gli e servito per arrivare al product-market fit, e ora devono far evolvere l'architettura per scalare. Gli ingegneri senior e gli architetti dal LATAM che forniamo hanno guidato questa transizione piu volte -- sanno cosa estrarre per primo, come evitare gli errori classici delle migrazioni distribuite, e come farlo senza fermare le consegne di funzionalita.
Perche questa e la chiave: il tuo business non puo fermarsi mentre migri. Gli utenti continuano a usare il prodotto. Il team di prodotto continua a chiedere funzionalita. La migrazione deve avvenire in parallelo a tutto il resto. E questo richiede ingegneri che l'hanno gia fatto.
Il tuo monolite sta diventando un collo di bottiglia? Parla con un CTO -- ti colleghiamo con architetti senior che hanno guidato questa transizione senza fermare le consegne.


