Microservizi: lo stile architetturale per le applicazioni moderne

12 minutes read
01 Giugno 2021

Un trend particolarmente affermato nello sviluppo di nuove applicazioni è l’utilizzo dei microservizi in ragione della loro flessibilità e versatilità. 
Ma che cosa sono i microservizi? 

I microservizi sono uno stile architetturale che prevede la realizzazione di applicazioni a partire dallo sviluppo di servizi modulari indipendenti – i microservizi, appunto – votati allo svolgimento di una determinata funzione. 

Un microservizio è un elemento software indipendente, che rappresenta ed esegue in autonomia una specifica funzione di business: per esempio, un microservizio CRUD è dedicato allo svolgimento di operazioni di creazione, lettura, aggiornamento ed eliminazione (create, read, update e delete) su una collezione di dati.
Ancora, il microservizio che chiamiamo “pagamenti” si occupa di effettuare il pagamento di una transazione commerciale; il microservizio “catalogo” si occupa di gestire un catalogo prodotti; il microservizio “prezzi” viene utilizzato per calcolare il prezzo di un prodotto; e così via.
Insieme i microservizi realizzano una transazione di business, come ad esempio l’acquisto di un prodotto online. 

Storia e caratteristiche distintive dell’architettura a microservizi

Questo approccio allo sviluppo di applicazioni non è completamente nuovo. 
In origine lo sviluppo applicativo era organizzato seguendo un approccio monolitico: il codice sorgente dell’app veniva eseguito in una singola unità di deployment.
Le applicazioni ideate e realizzate come monoliti garantivano una certa semplicità di progettazione ma portavano con sé una serie di limitazioni: scarsa capacità di evolvere il monolite con tecnologie nuove ed eterogenee, complessità nel garantire business continuity, limitata scalabilità e tempi di rilascio piuttosto lunghi. Non erano adatte a evolvere nel tempo per andare incontro alle nuove esigenze di business. 

È emerso così lo stile architetturale SOA (service‑oriented architecture), basato sull’idea di esporre servizi e funzionalità che siano riutilizzabili e facilmente integrabili con una o più applicazioni attraverso protocolli di comunicazione standard (per esempio SOAP, HTTP o JSON/HTTP), e un Enterprise Service Bus (ESB). Tuttavia, l’utilizzo di un ESB può rivelarsi uno approccio rischioso, poiché implica l’esistenza di un singolo punto di errore per l’intero sistema

Una prima evoluzione nella direzione dello stile architetturale a microservizi si trova nell’architettura esagonale (Hexagonal Architecture) – o Port Adapter – nata con lo scopo di creare componenti applicativi disaccoppiati, che possano quindi essere facilmente connessi al loro ambiente software tramite porte e adattatori. 

Lo stile architetturale a microservizi, invece, si distingue dagli altri approcci per una caratteristica che investe la fase di progettazione: ciascun servizio è concepito come una parte indipendente dell’architettura, con un solo scopo (l’esecuzione di una funzione), parametri ben definiti e che può essere sviluppata e rilasciata indipendentemente. 

I servizi espongono le informazioni e comunicano tra loro attraverso interfacce di programmazione (API), stream di eventi o message broker, che sono indipendenti dal linguaggio e garantiscono così una certa libertà e flessibilità al team di sviluppo. 

Inoltre, l’emergere delle tecnologie di containerizzazione, che permettono di eseguire diverse parti di un’applicazione in modo indipendente e sullo stesso hardware, ha agevolato l’affermarsi della pratica di utilizzare microservizi containerizzati alla base dello sviluppo di applicazioni cloud‑native. 

 

Indipendenza

Abbiamo già parlato dell’indipendenza dei microservizi come loro caratteristica fondamentale e distintiva: si tratta di una peculiarità che investe tutte le fasi di vita di ciascun servizio – progettazione, esecuzione, test, rilascio e successive evoluzioni. 
Questa caratteristica si riflette in diverse aree, dall’organizzazione del lavoro dei team, alla gestione dei rilasci e di eventuali malfunzionamenti. Ad esempio, i team potranno lavorare in modo indipendente allo sviluppo delle diverse funzionalità, senza creare dipendenze interne a parità di API esposte e consumate. 

I microservizi, essendo progettati e sviluppati come unità indipendenti, che eseguono una sola funzione e rispondo a una singola logica di business, possono evolvere o scalare in maniera autonoma, a seconda delle specifiche esigenze di business.
Ciascun microservizio può scalare orizzontalmente o verticalmente, evitando che il sistema debba essere scalato nella sua interezza, come è tipico delle applicazioni monolitiche.

Inoltre, dal momento che i servizi sono indipendenti dalle tecnologie sottostanti, anche queste possono evolvere o cambiare, evitando il lock‑in, senza impattare sul funzionamento dei servizi stessi e sull’esperienza dell’utente finale. 

 

Responsabilità

Come abbiamo anticipato, ogni microservizio è preposto allo svolgimento di una specifica funzione. Per questo, definire l’ampiezza e i limiti di responsabilità di ciascun microservizio è fondamentale: è un’attività che deve essere eseguita in fase di design, per avere un’applicazione bilanciata, flessibile, veloce, scalabile e facilmente manutenibile. 

Un ruolo centrale nella definizione dei confini di ciascun servizio è svolto dal principio della singola responsabilità (SRP), introdotto da Robert Cecil Martin: prescrive che ogni microservizio debba essere responsabile di una sola funzione. Questo principio può essere considerato il punto di partenza nella definizione dei limiti di ciascun microservizio, ma può essere utile seguire altre indicazioni: un ottimo modo per disegnare i microserivizi è approcciare il design con metodi  DDD – Domain Driven Design.  

In linea di massima, per definire correttamente quanto deve essere grande un microservizio è necessario valutare diversi punti, che prendono in considerazione il ruolo, i requisiti, la tecnologia e le esigenze di isolamento del singolo servizio.  

 

Disaccoppiamento e interoperabilità

I microservizi tipicamente espongono le funzionalità utilizzando un meccanismo di integrazione loosely‑coupled e indipendente dalla tecnologia (REST HTTP). 
Questo permette di utilizzare tecnologie (e linguaggi) diverse all’interno della stessa applicazione (es. Java, .NET, Python etc) e di farle evolvere nel tempo senza impattare sul risultato finale e sull’esperienza utente.
Inoltre, una comunicazione di tipo API RESTful offre vantaggi quali ridotto utilizzo di banda, grande flessibilità nel format di dati restituiti (XML, JSON,YAML etc.) e semplicità di integrazione con sistemi terzi.

 

Automazione 

I microservizi favoriscono l’implementazione di pratiche e processi automatizzati. 
Per esempio, si integrano facilmente nelle pratiche di Continuous Delivery e Continuous Integration, in cui l’obiettivo è automatizzare il più possibile i processi per avere una pipeline di deployment affidabile, ripetibile e semplice. 

In questo modo, ricorrendo all’utilizzo di strumenti per l’integrazione ed esecuzione dei processi che portano al delivery, è possibile gestire centinaia di microservizi da un’unica piattaforma, con un notevole risparmio di tempi e costi e una migliore governance dell’intero ciclo di vita del codice

I vantaggi di sviluppare con i microservizi

Come abbiamo visto, i microservizi hanno delle caratteristiche specifiche, che li distinguono dagli altri stili di sviluppo software. 
Realizzare un’architettura a microservizi vuol dire sviluppare le diverse funzioni di cui si compone come servizi modulari indipendenti. Questo porta con sé particolari vantaggi, che investono sia gli aspetti più tecnici, sia il punto di vista del business.

Vediamoli nel dettaglio. 

 

Adattabilità alle esigenze di business

Il primo vantaggio derivante dalle caratteristiche di indipendenza ed evolvibilità dei microservizi è la possibilità di modificare e adattare con semplicità e velocità il prodotto software secondo le esigenze del business. Trattandosi di una combinazione di elementi indipendenti, che comunicano tra loro attraverso un protocollo standard e possono scalare al bisogno, è possibile intervenire in tempi rapidi sulle singole feature per modificare, migliorare, evolvere o perfino stravolgere il prodotto finale, per rispecchiare le esigenze in continuo mutamento del business. In questo modo è possibile realizzare un’architettura applicativa in grado di evolvere con il mercato

Inoltre, utilizzando le API per l’esposizione delle informazioni verso l’esterno, i microservizi garantiscono un’ottima integrazione con servizi, applicazioni e sistemi esterni, offrendo al business la possibilità di sviluppare nuove partnership e accordi commerciali con terzi

 

Gestione semplificata del prodotto software

È sempre la natura indipendente dei microservizi a offrire diversi vantaggi nella gestione del software. In particolare, i principi di SRP e bounded context, che guidano la scrittura e l’evoluzione del codice, garantiscono che l’evoluzione del software sia lineare e semplificata in ogni suo componente.
Inoltre, la possibilità dei team di lavorare in modo indipendente e parallelo sulle singole feature offre ai CIO una governance semplificata del ciclo di evoluzione dell’intero prodotto software.

 

Affidabilità e semplificazione delle fasi di sviluppo e rilascio

L’integrazione con le pratiche di CI/CD, come abbiamo visto sopra, permette di lavorare con rilasci piccoli e frequenti, e di automatizzare il più possibile le operazioni di sviluppo, test e rilascio del codice. Questo garantisce non soltanto una maggiore semplicità di gestione e un notevole risparmio di tempo nelle diverse fasi che portano al rilascio del software, ma anche la realizzazione di una pipeline ripetibile e per questo affidabile
Inoltre, in un sistema frammentato in tante, più o meno piccole, entità indipendenti si svilupperanno necessariamente meno problemi di dipendenze, ed eventuali attività di rollback saranno più semplici da gestire, investendo una parte circoscritta e isolata.

Dal punto di vista della sicurezza, è consigliabile investire tempo e riporre particolare attenzione alle tematiche di responsabilità, comunicazione e dipendenze tra microservizi già nella fase di progettazione delle applicazioni. Ad esempio, un servizio che per sua natura risulti esposto a carichi di lavoro particolarmente alti o eventuali attacchi esterni, se correttamente isolato, non rischierà di diventare un point of failure per l’intera applicazione. Inoltre, la possibilità di isolare errori e malfunzionamenti semplifica la gestione degli stessi e migliora l’affidabilità e la sicurezza dell’intero sistema.

 

Containerizzazione e Kubernetes

Se parliamo di microservizi non possiamo non parlare di container e di Kubernetes, il tool di orchestrazione di container più diffuso e utilizzato al mondo.
La pratica della containerizzazione permette infatti di raccogliere in un unico container un’applicazione e tutte le dipendenze necessarie a farla funzionare, permettendo di distribuire il software in modo affidabile

Kubernetes  si è affermato come lo strumento ideale per orchestrare i container e realizzare architetture a microservizi performanti

 

Lavorare con i microservizi: il modello Feature Teams

Un buon modo per approcciare lo sviluppo a microservizi è quello di organizzare i team in modo da rispecchiare il modello di sviluppo – ciascuna funzionalità è un elemento indipendente e finito – che a sua volta ricalca la struttura dell’output finale. 
Questa struttura è chiamata feature team: team cross-funzionali che lavorano su singole feature in modo verticale, operando end‑to‑end su tutto il ciclo di vita della funzionalità che vanno a implementare. 

In questo modo, unendo competenze di back‑end, front‑end, UX/UI, progettazione e mantenimento di API, conoscenza delle logiche di business, test, deploy, operations etc. il team potrà gestire in autonomia le proprie funzionalità, con una visione d’insieme di quello che sarà il risultato finale. Il team è responsabile dei microservizi che sviluppa, dall’inizio alla fine. 

 

Punti di attenzione dello sviluppo a microservizi

Nonostante i numerosi e considerevoli vantaggi, anche questo stile architetturale porta con sé alcune criticità.

  • Testare un’intera applicazione a microservizi potrebbe essere macchinoso. In particolare, mentre testare un singolo microservizio è un’operazione semplice e piuttosto profittevole, eseguire il testing dell’intera applicazione richiede una serie di operazioni più articolate e una maggiore attenzione.
  • Nelle transazioni distribuite può essere complesso garantire la consistenza dei dati, aggiornati in parallelo da diversi microservizi. In questo contesto, il pattern architetturale Saga Pattern si sta affermando come pratica di successo. 
  • Effettuare il debugging dell’intera applicazione potrebbe richiedere molto tempo, poiché ciascun microservizio ha il proprio set di log. Potrebbe quindi essere necessario passare in rassegna parecchi log prima di individuare il punto in cui si verifica l’errore.
    Da questo punto di vista, quindi, risulta ancora più importante avere sempre il controllo e la visibilità su tutti i servizi in funzione, per monitorarne lo stato di salute e individuare tempestivamente eventuali punti di errore.
  • Governance: In contesti enterprise di grandi dimensioni, è normale avere centinaia o migliaia di microservizi in produzione, con diversi team di sviluppo, ciascuno dei quali lavora in autonomia secondo le proprie abitudini. In questo ambito, per avere una governance chiara di tutto l’ecosistema di microservizi è raccomandabile standardizzare il più possibile processi e metodi. A supporto di questo obiettivo troviamo diversi strumenti, come Mia‑Platform Console che supporta i team di sviluppo e contemporaneamente aiuta a presidiare le attività IT e governare il sistema nella sua interezza.
     
  • All’aumentare della complessità cresce la necessità di avere un sistema di monitoraggio valido ed efficace. Tra le best practice raccomandate troviamo ad esempio l’utilizzo di strumenti di monitoraggio e orchestrazione dei container in cui i microservizi sono eseguiti; una buona strategia di API security che includa il monitoraggio delle chiamate API che interessano i microservizi; la visibilità continua sullo stato di salute di ciascun servizio, così da poter intervenire al bisogno.
  • Come abbiamo visto, lo stile architetturale a microservizi consente di utilizzare gli strumenti e i linguaggi che predilige. Per questo, mantenere la documentazione chiara, aggiornata e comprensibile è fondamentale: non può essere considerata uno strumento accessorio, ma deve essere un passaggio irrinunciabile del ciclo di sviluppo. Questo aspetto risulta particolarmente importante per favorire l’integrazione con terzi. 

Questi punti di attenzione, se non correttamente governati, possono generare preoccupazione: in questo articolo, Davide Tantillo, Francesco Francomano e Giulio Roggero raccontano le sette buone pratiche per scrivere microservizi e sentirsi sereni dopo averli rilasciati, frutto dell’esperienza di aver progettato e messo in produzione migliaia di microservizi in container con Kubernetes.

 

Migrare le tue applicazioni ai microservizi

Questo modello di sviluppo, oltre che per approcciare applicativi e progetti digitali da zero, può essere utilizzato anche per modernizzare sistemi legacy ancorati a un’architettura centralizzata. 

Sviluppando microservizi appositi, è possibile disaccoppiare i sistemi dai canali, guadagnando autonomia di sviluppo e gestione: i sistemi sottostanti continuano a lavorare – alleggeriti dai carichi di lavoro potenzialmente eccessivi – ma non hanno un rapporto diretto con i canali. 
I canali, liberi dai vincoli di prestazioni e disponibilità dei sistemi, permettono di erogare un’offerta integrata e flessibile di prodotti e servizi performanti, che possono essere arricchiti, scalati e fatti evolvere liberamente. 

Inoltre, adottando un approccio incrementale, è possibile migrare progressivamente le diverse funzioni verso un nuovo sistema più leggero, flessibile ed evolvibile. 


Leggi il caso di una grande compagnia assicurativa che ha saputo trasformarsi e migliorare la manutenibilità e la governance dei propri sistemi IT con Mia‑Platform. 

Infine, se vuoi approfondire il tema dei microservizi, abbiamo selezionato cinque libri sulle architetture a microservizi che secondo noi non dovresti perderti. 

New call-to-action
Back to start ↑
TABLE OF CONTENT
Storia e caratteristiche distintive dell’architettura a microservizi
I vantaggi di sviluppare con i microservizi
Containerizzazione e Kubernetes
Lavorare con i microservizi: il modello Feature Teams
Punti di attenzione dello sviluppo a microservizi
Migrare le tue applicazioni ai microservizi