Vai al contenuto

Guide

Modernizzare un'applicazione legacy: da dove cominciare

· 6 min di lettura

Per modernizzare un'applicazione legacy, cominciate mettendo per iscritto perché deve cambiare, poi valutate insieme il codice e la produzione. Stabilizzate il sistema e mettete dei test intorno al comportamento da cui dipende il business prima di cambiarne la struttura. Con questa rete di sicurezza, sostituite il sistema un pezzo alla volta, migrate i dati con metodo e riservate la riscrittura completa al raro caso in cui c'è poco da salvare.

Chiarite il motivo di business prima di toccare il codice

Modernizzare costa, quindi partite dal motivo. I più comuni sono un runtime o un framework a fine vita, modifiche che richiedono settimane perché ogni rilascio rompe qualcosa, un sistema che una sola persona capisce, o una piattaforma che non regge ciò di cui il business avrà bisogno in futuro. Ogni motivo porta a un primo passo diverso.

Mettete per iscritto il motivo con una misura da verificare in seguito, come la frequenza dei rilasci, il numero di incidenti o il tempo che una modifica tipica impiega per arrivare agli utenti. Senza questa misura, la modernizzazione diventa un progetto tecnico senza fine, difficile da difendere alla prossima revisione del budget.

Valutate codice e produzione prima di decidere qualsiasi cosa

Una valutazione vi dice che cosa avete davvero. Tenetela breve e fate in modo che si concluda con un report scritto e un primo passo raccomandato. Leggete il codice, ma leggete anche la produzione: log, incidenti, query lente e il modo in cui si fanno i rilasci. I problemi peggiori spesso stanno intorno al codice più che dentro.

  • Versioni di runtime, framework e librerie, e quali non ricevono più correzioni di sicurezza
  • Quali parti cambiano più spesso e quali si rompono più spesso, secondo lo storico delle versioni e il registro degli incidenti
  • La copertura dei test sui percorsi da cui dipende il business
  • Come l'applicazione viene compilata, configurata e rilasciata, e chi è in grado di farlo
  • Il modello dei dati, le sue dimensioni e quali altri sistemi leggono o scrivono nello stesso database
  • Le persone che conoscono il sistema, e ciò che sanno solo loro

Stabilizzate prima la produzione, così il lavoro ha una base solida

Se il sistema si guasta ogni settimana, la modernizzazione verrà interrotta ogni settimana. Correggete prima ciò che causa gli incidenti: aggiungete monitoraggio e allarmi sui percorsi critici, automatizzate build e deploy perché i rilasci siano ripetibili, e portate segreti e configurazione fuori dal codice.

Questi passi ripagano subito e rendono più sicuro ogni passo successivo. Mostrano anche presto se il team riesce a modificare il sistema senza romperlo, cosa che conviene sapere prima di impegnarsi in un piano più ampio.

Create una rete di test intorno al comportamento su cui contate

Il codice legacy di solito ha pochi test, e il suo comportamento documentato corrisponde di rado a quello reale. Prima di cambiare la struttura, scrivete test di caratterizzazione: test che registrano ciò che il sistema fa oggi, compresi i suoi strani casi limite, così che qualsiasi cambiamento di comportamento si manifesti come un test che fallisce.

Cominciate dai bordi, con test che chiamano l'applicazione attraverso la sua API o la sua interfaccia utente e ne controllano i risultati, perché sopravvivono ai cambiamenti interni. Per calcoli e report, fate passare input reali nel vecchio e nel nuovo codice e confrontate gli output. Aggiungete test più granulari a ogni parte man mano che la ristrutturate. Il nostro articolo sull'aggiornamento di un'applicazione Java 8 critica mostra la stessa rete di sicurezza applicata a un aggiornamento del runtime.

Sostituite il sistema un pezzo alla volta invece di riscriverlo

Una riscrittura completa sembra pulita sulla carta, ma il vecchio sistema continua a girare e a cambiare mentre quello nuovo cerca di raggiungerlo, e ogni comportamento non documentato va riscoperto strada facendo. Ecco perché le riscritture richiedono così spesso più tempo del previsto, mentre il business aspetta.

L'alternativa abituale è il pattern strangler fig («fico strangolatore»). Mettete uno strato di instradamento, come un reverse proxy o un API gateway, davanti all'applicazione legacy. Costruite una funzionalità alla volta nel nuovo codice e indirizzatevi il traffico di quella funzionalità quando ha dato prova di funzionare. Il vecchio sistema si riduce finché non si può spegnere, e il business ottiene valore a ogni passo.

Una riscrittura può comunque essere la scelta giusta: quando la base di codice è piccola e il suo comportamento ben compreso, oppure quando la piattaforma su cui gira non può restare in vita abbastanza a lungo per una sostituzione graduale. Decidete con criteri scritti, non sull'onda della frustrazione.

Trattate i dati come una migrazione a sé

Il codice si può sostituire a fette; i dati sono più difficili da dividere. Finché il codice legacy e quello nuovo condividono un database, ogni modifica allo schema va coordinata. Decidete presto quale sistema è la fonte di verità per ciascun tipo di dato, ed evitate che due sistemi scrivano lo stesso record senza una regola su quale scrittura prevale.

Quando una funzionalità si sposta, spostate o sincronizzate i suoi dati con metodo: script di migrazione testati su una copia della produzione, oppure una sincronizzazione continua mentre girano entrambi i sistemi. Pianificate come riconcilierete i due, per esempio con conteggi e checksum giornalieri, e mantenete la possibilità di tornare indietro finché i numeri non coincidono.

Ordinate il lavoro per rischio e valore, e mostrate presto i progressi

Ordinate il lavoro in modo che ogni passo riduca un rischio o porti qualcosa che il business può vedere. Una sequenza comune è stabilizzare e automatizzare, aggiungere test, aggiornare il runtime, poi estrarre le funzionalità che cambiano più spesso. Le parti stabili e toccate di rado possono aspettare, a volte a tempo indeterminato.

Tenete il piano breve e rivedetelo dopo ogni passo, perché ciò che imparate cambierà l'ordine. I nostri ingegneri hanno lavorato così su sistemi critici. Tramite Sopra Steria hanno guidato la migrazione da Java 8 a Java 16 di un'applicazione critica di day-trading sul gas, e come parte del team del programma cloud di Crédit Agricole abbiamo valutato ogni applicazione che abbiamo migrato per decidere se aggiornarla o ricostruirla. Se volete una valutazione del vostro sistema, o un team che porti avanti il piano, SDK Enterprises fa entrambe le cose con un unico contratto.

Punti chiave

  • Mettete per iscritto il motivo di business della modernizzazione, con una misura da verificare in seguito.
  • Valutate insieme codice e produzione prima di scegliere tra aggiornamento, sostituzione graduale e riscrittura.
  • Stabilizzate la produzione e mettete test di caratterizzazione intorno al comportamento critico prima di cambiare la struttura.
  • Sostituite il sistema un pezzo alla volta dietro uno strato di instradamento, a meno che una riscrittura non sia chiaramente più piccola e più sicura.
  • Pianificate titolarità, sincronizzazione e riconciliazione dei dati come una migrazione a sé.

Domande frequenti

Conviene riscrivere da zero la nostra applicazione legacy?

Di solito no. Una riscrittura insegue un sistema che continua a cambiare e deve riscoprire comportamenti che nessuno ha documentato. Sostituitelo gradualmente, a meno che la base di codice non sia piccola e ben compresa, o legata a una piattaforma che non si può mantenere in funzione.

Quanto tempo serve per modernizzare un'applicazione legacy?

Dipende dalle dimensioni del sistema, dalla copertura dei test, da quanto sono intrecciati i dati e da quanto deve cambiare. Una breve valutazione vi dà un piano realistico e un primo passo abbastanza piccolo da essere completato e misurato, invece di un'unica data per l'intero lavoro.

Possiamo continuare a rilasciare funzionalità mentre modernizziamo?

Sì, ed è bene farlo. La sostituzione graduale permette al team di consegnare funzionalità nel nuovo codice mentre il sistema legacy continua a girare. Concordate quanta parte del tempo del team va alla modernizzazione, così lo sviluppo di nuove funzionalità non la assorbe senza che nessuno se ne accorga.

Diteci di cosa avete bisogno.

Qualcosa da sviluppare, persone da trovare o una domanda a cui rispondere. In una call di 30 minuti vi ascoltiamo e vi diciamo con franchezza come possiamo aiutarvi, e cosa servirebbe.