Viaggio nel mondo a servizi, come prepararsi per l'avventura
Le 7 sfide da affrontare nella migrazione da monolite a miniservizi
1. 7 sfide da affrontare nella
migrazione da Monolite a mini-servizi
LUCA ACQUAVIVA lacquaviva@imolainformatica.it @lacquaviva
GIACOMO FIORINI gfiorini@imolainformatica.it @gfiorini
GUIDO RAVAGLI gravagli@imolainformatica.it
IDI 2019 - BOLOGNA 08/03/2019
2. Contesto
Decine di virtual machine
Milioni di righe di codice
Centinaia di developer
singola codebase
Migliaia di REST API
Bassa velocità
evolutiva
Presenza di
framework custom
Business critical
Change
centralizzato
Decine di migliaia di utenti
concorrenti
Logiche fortemente
accoppiate
Perturbazioni localizzate
impattano l’intero sistema
5. Cambiare modello architetturale?
Aumenta la complessità
deploy
infrastruttura
tecnologie
organizzazione
processi
Affrontare un cambiamento architetturale richiede la
consapevolezza delle problematiche che si vogliono risolvere e dei side
effect a cui si va incontro
Evolvere velocemente senza
interruzione
Maggiore resilienza
Deploy e scalabilità
indipendenti
7. Monolith First
1. Almost all the successful microservice stories have started witha
monolith that got too big and was broken up
2. Almost all the cases where I've heard of a system that was built as
a microservice system from scratch, it has ended up in serious
trouble.
https://martinfowler.com/bliki/MonolithFirst.html
Affronto l'evoluzione separando il monoliteper gruppi di funzionalità
8. You’re Not Actually Building
Microservices
"... a distributed monolith is the worst of all worlds. You’ve taken the
relative simplicityof a single monolithic codebase, and you’ve traded
it in for a deeplyintertwineddistributed system. So, are you building
microservices?"
https://www.simplethread.com/youre-not-actually-building-
microservices/
Le architetture MSA non sono per tutti, quando il contesto non permettedi
riscrivere da zero l'evoluzione non può che essere graduale.
9. Miniservices
"A miniservice seems to be a simpler, pragmatic way of doing
microservices or something closely related. For example, each
microservice must handle its own data, miniservices may share
data"
— Arnaud Lauret
https://thenewstack.io/miniservices-a-realistic-alternative-to-microservices/
11. Modelli a confronto
“Don’t confuse architectural perfection with business value.”
— Ross Garrett
Deploy indipendenteper
funzionalità
Deploy indipendenteper
gruppo di funzionalità
Singolaunita di deployper
tutto il sistema
Data consistency Data consistency Eventualconsistency
Looser coupling, greater agility
Lower complexity, easy to run
monolith miniservices microservices
Debolmente accoppiatiAccoppiamentoper gruppo
di funzionalità
Fortemente accoppiato
12. Non esiste un modelloarchitetturale"corretto" in termini assoluti,è sempre
questione di un trade-off guidato solo dalla consapevolezza e dalle esigenze.
Se voglio cambiare solo latecnologia posso e dovrei farlo senza stravolgere
l’architettura
Per ora mi limito ad uno step intermedio a mini-servizi l’unico sensato che non
preclude una possibile evoluzione successiva
14. Perché farlo
Limiti di infrastruttura
La scalabilitàdell’infrastrutturaha
raggiunto il limite fisico
Tempi elevati di avvio di una nuova
istanza
Limitazioni tecnologiche
La dimensione del progetto è critica
Difficoltà nel portare avanti le
evoluzioni del prodotto
Gruppi di developer di grandi
dimensioni che lavorano sullastessa
codebase
Difficoltà nel circoscrivere i problemi
e a governare lo stato della
codebase
L'applicazione è modulare
Le logiche di business sono
organizzate in moduli indipendenti
15. Perché non farlo
Le finte motivazioni non valgono
La sola innovazione tecnologica non giustifica un cambiamento di
modello architetturale
Seguire il trend del momentonon è sempre la scelta giusta
Aumenta la complessità senza benefici
Maggiore effort per il governo (pre e post change)
Maggiore effort richiesto per il deploy
17. Conoscenza
Conosco realmente lo stato del sistema?
Quali sono le funzionalità centralizzate o condivise?
Come è fatta l’architettura?
Le parti che lo compongono sono uniformi?
Quali sono le funzionalità?
Quali sono le funzionalità non osservabili?
Se non sono in grado di rispondere devo ricostruirne lo stato:
- Difficilmente a big bang
- Lo posso fare in modo incrementale, per domini funzionali
18. Come recupero le informazioni?
Individuare i pattern «problematici»
Presenza di comportamenti Stateful (utilizzo di sessioneweb)
Modello dati condiviso
Design che massimizza il riuso
DRY – utilizzo di shared library e framework (acceleratori) custom
Analisi del codice con strumenti custom o di mercato
L'unica documentazione realmente attendibile è il codice
API Dependencies
20. Strategia
Non esiste la strategia«giusta», …
… devo garantire evoluzione continua senza interruzione
Trasformazione ed adeguamento tecnologico a big bang e successivamigrazione
architetturale?
Trasformazione incrementale, sia tecnologicache architetturale?
.. la strategiadipende dal contesto, dallo stato dell’applicazione e del sistema.
21. Una possibile strategia
Separo il monoliteper ambiti funzionali
Strangler pattern (rivisitato – non separo i dati)
Mantengo/converto le logiche di business come insieme
di dipendenze modulari risolte in fase di build
Se vi sono funzionalità comuni che devono essere rese indipendenti
valuto la creazione di un micro-servizio
Inizio a segregare le funzionalità cross come servizi esternalizzati
disaccoppiati
E se questi sono fortemente intrecciati? Quanto mi serve per riscrivere
l'intero codice?
22. Strategia di migrazione
Minimizzare le modifiche funzionali e gli impatti sul client in modo
tale da non rischiare di introdurre regressioni
Interventi limitati all’adeguamentotecnologico/infrastrutturale
Mantenere temporaneamente l’esposizione delle API del
componente migrato anche sul «vecchio» monolite
Rollback più rapido in caso di problemi dopo il rilascio
Rollout incrementale
23. Challenge 4
Il business non si ferma
QUALSIASI INTERVENTO IN APPLICAZIONI CHE PRODUCONO PROFITTO
NON PUÒ CAUSARE UN FERMO
24. Evoluzione continua senza
interruzione
Applicazioni business critical non si possono fermare, la strategiascelta
deve prevedere evoluzione del sistema senza fermi
Cambia l'infrastruttura
Cambia l'organizzazionedel progetto
Cambiano i processi
Deve cambiare la cultura delle persone
Devo mettermi nelle condizioni di sfruttare una migrazione graduale
abilitando se possibile pattern di switch-back sul monolite
25. Reattività al cambiamento
Non dimentichiamoci che mentre avviene la migrazione a mini-
servizi, la base di codice del monolite evolve(RAPIDAMENTE)
Allineare manualmente il codice dei mini-servizi ad ogni variazione
del monolite è un'operazione onerosa
Devo munirmi di strumenti che mi abilitino ad assorbire facilmente le
evoluzioni del software.
26. Tools
Archetipi Maven
Struttura dei progetti
Mapping Api-to-miniservices
Estrazione automatica +
assegnazione da parte di esperti di
dominio
Codice sorgente del monolite
27. Generazione dei progetti
A. Startup del progetto più veloce:
Non devo partire da zero per ogni miniservizio.
B. Modifiche a codice sorgente, archetipo e api si risolvono in merge:
È possibile revisionare le modifichee decidere quando portarle sul
ramo di sviluppo principale.
29. Modello di sviluppo
Monolite: test e run in locale possibile con la configurazione di un
solo ambiente (o l'utilizzo di una vm)
Manuali di configurazione, parametri di avvio, etc..
"Costruirsi" un ambiente locale è tutt'altro che banale
Gran parte dei test sono effettuati direttamente sugli ambienti
Mini-servizi: test e run locale sono differenziati per progetto
Progetti autocontenuti (configurazioni e puntamenti sono contenute
nel repository sorgente)
IaC sfrutto le configurazioni del progetto applicativo per la definizione
dell’ambiente di run-time locale
Build, deploy (tramite docker) e test integrati nel ciclo di build maven
31. Librerie vs Servizi
Tutto ciò che è condiviso nel codice del monolite pone un problema
di come gestire il riuso
Libreria → Servizio(?)
Coesistenza di modellidiversi fra i mini-servizi?
Se non si riesce complico il change (es. un cambio di modello dati
condiviso richiede il re-deploydi tutti i mini-servizi che lo
condividono)
33. Does it work?
Come faccio a testare i nuovi miniservizi?
Aspetti funzionali
Test basati sul confronto tra
monolite e miniservizi
Aspetti non osservabili da un
utente
Logging
Tracciatura
Caching
34. Test funzionali
Approccio a Black-Box basato su
comparazione:
Pro: facileda implementare (e
automatizzare), non serve una conoscenza
dettagliata del dominiofunzionale
Contro: scarsa copertura nei casi di logiche
complesse e dipendenti dai dati
35. Test non funzionali
Aspetti non direttamente osservabili da un utente, ma non per questo
meno importanti.
Tracing: dati di tracciatura inseriti in basi di dati dedicate per determinate
operazioni, rispettiamo il formato e i dati?
Log: il servizionuovo logga in maniera iso-funzionale?
Utilizzo Cache: l'applicazione utilizzauna cache applicativa...i dati sono
salvati in manieracoerente?
Performance: i mini-servizi rispettano i requisisti di performance richiesti
dall'applicazione?
37. Cambiare tutto ma…
Nessuno deve accorgersene! (o quasi… ☺)
Ai gruppi di sviluppo abbiamo reso trasparente
• il porting tecnologico
• il porting da monolite a mini-servizi(non abbiamo – ancora –
spezzato il DB!)
Mantenendo, per quanto possibile, la stessa base di codice
Anche l’utente non si deve accorgere di nulla
• nessuna interruzione di servizio
• nessun degrado nelle performance
38. Supportare il cambiamento
Per quanto si possa rendere indolore il
cambiamento è necessario mettersi nei panni:
Dello sviluppatore: agevolare il passaggio al
nuovo modellodi sviluppo, affiancamento,
supporto a modifiche in-progress
Di chi gestisce il Change dell'applicativo: la
gestione si complica, ma se ho una conoscenza
completa delle dipendenze posso governarlo.
40. Si può fare
Affrontando queste 7 sfide siamo riusciti a portare già in produzione parte del
monolite
Lo abbiamo fatto gradualmente
Anche se incrementale e graduale il cambiamento architetturale ha dei vantaggi
Già emergono ulteriori punti di evoluzione
Come tuttele architetture anche quella a mini-servizi ha dei limiti, per alcuni dei
servizi o per le librerie comuni, avrà senso un’evoluzione a micro-servizi
Abbiamo già incrementato l’agilità
Il deploy indipendente per dominio funzionale migliora la resilienza del sistema e
abbatte i tempi di rilascio e rende scaling e monitoraggio più efficiente