Strangler Fig Pattern: Come Migrare un Monolite in Modo Incrementale
Come applicare lo strangler fig pattern per migrare un monolite in modo incrementale: instrada, sostituisci e ritira senza riscritture big-bang o downtime.
In questo articolo:
- Cos’è lo strangler fig pattern
- Le tre fasi: seam, route, replace
- Applicare strangler fig alla migrazione a microservizi
- Errori comuni e come evitarli
- Conclusione
Lo strangler fig pattern è una strategia di migrazione che sostituisce un sistema legacy in modo incrementale instradando le richieste attraverso un livello facade. Le nuove funzionalità vengono costruite in un nuovo sistema. Man mano che ogni capacità viene reimplementata, il traffico per quella capacità viene instradato dal sistema legacy al nuovo. Nel tempo, il nuovo sistema gestisce sempre più traffico, mentre il legacy gestisce sempre meno, fino a quando non può essere ritirato.
Il nome deriva dall’albero del fico strangolatore, che cresce attorno a un albero ospite e alla fine lo sostituisce. Il sistema legacy continua a funzionare durante l’intera migrazione. Gli utenti non notano alcuna interruzione. Gli ingegneri consegnano funzionalità al nuovo sistema durante tutta la migrazione invece di congelare lo sviluppo per completare una riscrittura big-bang.
Cos’è lo strangler fig pattern
Lo strangler fig pattern è stato descritto da Martin Fowler come l’approccio standard per sostituire i sistemi legacy che non possono essere portati offline per una riscrittura completa. Differisce da una riscrittura diretta in tre modi.
Primo, produce un sistema funzionante ad ogni passo. In qualsiasi momento durante la migrazione, la combinazione di vecchio e nuovo è un sistema funzionale e distribuibile. Non c’è alcun periodo in cui né il vecchio né il nuovo sistema è completamente funzionale.
Secondo, è reversibile. L’instradamento del traffico tra vecchio e nuovo è controllato da uno strato (un proxy, un gateway, un feature flag) che può essere invertito rapidamente. Se la nuova implementazione di una capacità ha un bug, l’instradamento torna al vecchio sistema senza un deployment.
Terzo, consegna valore durante l’intera migrazione. Poiché il nuovo sistema è in produzione fin dalle prime fasi, può essere migliorato, esteso e monitorato. I team non aspettano sei mesi per vedere se la riscrittura ha avuto successo.
Lo strangler fig pattern è particolarmente rilevante per i progetti di scomposizione del monolite dove l’obiettivo è estrarre servizi da un codebase legacy mantenendo la disponibilità in produzione.
Le tre fasi: seam, route, replace
Fase 1: Identifica il seam. Un seam è un confine nel sistema legacy dove è possibile introdurre un nuovo comportamento senza modificare il codice esistente. In un’applicazione web, il seam più comune è il livello di routing HTTP.
Introduce un facade o proxy davanti al sistema legacy. Inizialmente, il proxy passa tutte le richieste al sistema legacy invariate. Questo è un deployment a rischio zero che stabilisce l’infrastruttura di routing che userai durante l’intera migrazione.
Fase 2: Instrada selettivamente. Scegli la prima capacità da migrare. I candidati tipici sono: funzionalità che vengono attivamente cambiate (alta frizione di sviluppo), funzionalità che devono scalare diversamente dal resto del sistema, o funzionalità ben comprese e a basso rischio da reimplementare.
Implementa la capacità nel nuovo sistema. Quando è pronta per la produzione, aggiorna il proxy per instradare le richieste per quella capacità al nuovo sistema. Il sistema legacy gestisce ancora tutto il resto.
A questo punto, esegui entrambi i sistemi simultaneamente per la capacità migrata se hai bisogno di fiducia nella nuova implementazione. Il proxy può chiamare entrambi, confrontare gli output e servire il risultato del legacy fino alla risoluzione delle discrepanze.
Fase 3: Sostituisci e ritira. Continua a migrare le capacità una alla volta. Con ogni migrazione, il sistema legacy gestisce meno traffico. Una volta che tutte le capacità sono state migrate e il sistema legacy riceve zero traffico, ritiralo.
Il passo di ritiro è spesso sottovalutato. I sistemi legacy accumulano dipendenze nascoste: batch job, strumenti interni, script occasionali e accesso diretto al database da altri sistemi. Prima di ritirare il sistema legacy, controlla tutte le sue connessioni in entrata e assicurati che ognuna sia stata migrata o decommissionata.
Applicare strangler fig alla migrazione a microservizi
Quando l’obiettivo è passare da un monolite a microservizi, lo strangler fig pattern fornisce il percorso di migrazione. Il proxy diventa un API gateway. Ogni servizio estratto gestisce uno specifico sottodominio della logica di business. Il monolite si riduce man mano che i servizi vengono estratti.
Le decisioni chiave in una migrazione strangler fig a microservizi:
Cosa estrarre per primo. Estrarre la capacità ad alto traffico per prima massimizza il beneficio operativo della nuova architettura fin da subito. Estrarre la capacità più indipendente per prima minimizza il rischio. Per una prima estrazione, favorisci la capacità più indipendente: una con stato condiviso minimo con il resto del monolite e confini ben definiti.
Migrazione dei dati. Quando una capacità viene estratta in un nuovo servizio, il servizio ha bisogno del proprio data store. La strategia di migrazione dei dati è la parte più complessa di qualsiasi scomposizione del monolite.
Confini delle transazioni. Le transazioni distribuite tra servizi sono costose e fragili. Prima di estrarre una capacità, identifica se partecipa a transazioni con altre capacità che rimarranno nel monolite.
Errori comuni e come evitarli
Estrarre troppo troppo velocemente. Lo strangler fig pattern funziona perché ogni estrazione è piccola e reversibile. Estrai una capacità alla volta.
Non investire nel livello proxy. Il proxy è il centro operativo della migrazione strangler fig. Ha bisogno di monitoraggio, logging, circuit breaker e la capacità di instradare il traffico con granularità fine.
Migrare la complessità del monolite nei nuovi servizi. Lo scopo della migrazione non è solo eseguire lo stesso codice in un nuovo modello di deployment. Se una capacità nel monolite ha una complessità ciclomatica di 80 e nessun test, estrarla in un microservizio produce un microservizio con complessità ciclomatica 80 e nessun test.
Nessun piano di ritiro chiaro. Senza un piano impegnato per ritirare il sistema legacy, la migrazione strangler fig tende a bloccarsi. Il sistema legacy finisce per gestire una lunga coda di casi limite e funzionalità raramente utilizzate che vengono deprioritizzate indefinitamente.
Conclusione
Lo strangler fig pattern è l’approccio standard per sostituire un monolite legacy in modo incrementale. Consegna valore durante l’intera migrazione, mantiene la disponibilità in produzione e mantiene l’opzione di invertire la rotta ad ogni passo.
La complessità è nell’esecuzione: migrazione dei dati, confini delle transazioni e la disciplina di estrarre in modo incrementale piuttosto che tentare una scomposizione big-bang. I team che eseguono questa disciplina in modo consistente completano migrazioni che avrebbero richiesto 18 mesi come riscritture big-bang in 6-8 mesi di consegna incrementale.
Hai un codebase con questi problemi? Parliamo del tuo sistema