L’affermazione del modello di cloud computing e le lezioni imparate nella gestione di software distribuito hanno portato all’ideazione di uno stile architetturale basato su microservizi, in cui il concetto di web services, di flussi e di scambio di messaggi non venga utilizzato solo nei grandi sistemi, ma diventi pratica comune in tutti i tipi di applicazione, anche le più piccole, portando di fatto alla fine dell’applicativo monolitico.
Microservizi: una panoramica
Qualcosa sta bollendo in pentola. Qualcosa che rivoluzionerà il modo con il quale siamo abituati a pensare e a progettare il software. Qualcosa di apparentemente marginale e settoriale ma che lentamente acquisterà spazio fino al punto di ribaltare tutto, fino al punto di stravolgere le abitudini. Sto parlando dei microservices, ossia dello stile architetturale introdotto, o comunque reso noto, da Fowley nell’ormai famoso post “Microservices” [1]. Di che si tratta? Al momento non esiste molta letteratura a riguardo, fatta eccezione per tanti post su blog e qualche primo libro che si sta affacciando sul mercato.
Software distribuito
Non è possibile perciò fornire definizioni molto precise sebbene l’idea centrale appaia chiara: i microservices spostano l’accento sulla distribuzione del software piuttosto che sulla sua concentrazione in applicazioni cosìdette monolitiche. In realtà la progettazione di sistemi distribuiti non è certo una novità che viene introdotta per la prima volta dall’approccio a microservices, ma senza ombra di dubbio i microservices sembrano volersi candidare a pratica riconosciuta e soprattutto diffusa per la progettazione di software, qualsiasi tipo di software.
Ed è qui che credo stia quel “qualcosa” che bolle in pentola, quell’elemento che ha le potenzialità per scardinare i normali processi di produzione del software: parlo dell’idea di rendere “normale” l’utilizzo di software distribuito per la realizzazione di sistemi anche di piccolo taglio. I sistemi distribuiti, infatti, sono generalmente utilizzati laddove non si può fare a meno di utilizzarli, dove cioè lo scenario implementativo è tale per cui si è forzati ad adottare un profilo distribuito nel design di sistemi per il semplice motivo che quello monolitico non è utilizzabile.
Gli scenari che immediatamente vengono in mente sono ad esempio quelli tipici che deve affrontare un system integrator: far colloquiare diversi applicativi tra di loro. Si pensi banalmente a uno scenario di integrazione tra un ERP SAP ed un e-commerce realizzato da una terza parte. Lo scenario è distribuito poiche’ sia l’ERP SAP che l’e-commerce risiedono e vengono eseguiti su macchine diverse e, verosimilmente, su piattaforme diverse. È chiaro che in questi scenari, la scelta di adottare una soluzione distribuita per realizzare l’integrazione diventa obbligata.
Microservices: approccio distribuito sempre
Con i microservices invece, si va ad utilizzare un approccio distribuito sempre e comunque. Non importa lo scenario, non importa l’obiettivo: la soluzione è sempre distribuita. È chiaro che se questo modo di sviluppare software si diffonderà, in futuro i programmatori potrebbero ragionare normalmente pensando al software distribuito come a qualcosa di normale e non di “eccezionale”, come la scelta ovvia e non come ad una scelta dettata da necessità particolari. Anzi, la visione potrebbe essere addirittura ribaltata: la scelta di procedere con un software monolitico piuttosto che distribuito diventerà il caso particolare piuttosto che la norma.
Da questa osservazione si capisce bene il perche’ parlo di possibile “rivoluzione” nel titolo; sì, perche’ se mai il paradigma distribuito diventasse cosa concreta nel prossimo futuro, be’ allora vorrebbe dire che sarà cambiato il modo di pensare dei programmatori e che all’interno del loro immaginario progettuale saranno cambiati i riferimenti e i modelli da utilizzare. Una rivoluzione con la R maiuscola insomma. L’informatica d’altra parte, non è nuova a questo genere di rivoluzioni; anzi, l’informatica è forse più di altre la scienza delle rivoluzioni, la scienza del cambiamento continuo dei paradigmi e delle abitudini. Non dobbiamo perciò stupirci di fronte a questa possibilità, ma dobbiamo anzi cercare di capirla e cavalcare le grandi opportunità che essa offre.
Le caratteristiche dei microservices
Partiamo dal nome, che già di per sè ci fornisce alcune informazioni sulle origini dei microservizi. La parola microservice è ottenuta come composizione di due parole: micro e service. Delle due la più importante è la seconda, service, poiche’ rappresenta il processo storico da cui provengono i microservices ossia il mondo dei servizi; la prima, micro, rappresenta l’elemento innovativo che va a rinnovare appunto l’approccio a servizi. L’approccio a servizi così come lo si intende qui è quello che proviene dal mondo delle SOA (Service Oriented Architectures) ossia l’insieme di specifiche internazionali, unitamente ad alcune tecnologie, che ha portato alla definizione dei Web Services. Questi ultimi sono nati essenzialmente come soluzione al problema dell’integrazione tra macrosistemi operanti su piattaforme differenti; sono nati cioè con l’obiettivo di fare interoperare in modo organico e non occasionale sistemi tra loro differenti.
Service
Le famiglie di tecnologie collegate ai Web Services sono cresciute molto nel corso degli ultimi dieci anni e si sono anche diffuse prima in progetti di dimensioni importanti fino alla situazione attuale in cui vengono utilizzate anche per progetti di dimensioni più contenute. In tutti questi casi, le funzionalità di un sistema informativo vengono suddivise in servizi e poi organizzate a loro volta con servizi di livello superiore in generale chiamati orchestratori. Ciascun servizo, ciascun Web Service, è un artefatto software in grado di fornire funzionalità verso l’esterno e indipendente dal contesto in cui è inserito. Queste caratteristiche lo rendono distribuibile, ossia eseguibile su una qualsivoglia macchina e su una qualsivoglia piattaforma.
La cosa importante è che le sue funzionalità siano disponibili sempre quando servono, ossia sempre quando vengono richiamate. Dal punto di vista del design del software perciò, i Web Service hanno introdotto una vera e propria metodologia per pensare e realizzare sistemi distribuiti a servizi. È inutile negare, però, come le tecnologie a Web Services siano spesso ostiche da gestire e non sempre soddisfino quei requisiti iniziali di favorire l’integrazione tra sistemi diversi in modo semplice e veloce. Interamente basate su XML, pagano il prezzo di un overhead legato proprio a questo standard che sì è molto diffuso, ma che porta a costi alti sia in termini di progettazione che di manutenzione.
Micro
Su questo stato dell’arte vediamo ora il significato della parola “micro” ed entriamo nel mondo dei microservices. I micorservices nascono con l’intenzione di mantenere una progettualità basata sui servizi ma con un carico tecnologico molto più leggero rispetto a quello dei Web Services. Nei microservices perciò si tende ad utilizzare tecnologie più leggere e semplici da gestire rispetto al mondo SOA, così da poter creare servizi in modo rapido e agevole e, soprattutto, più facili da deployare o “spostare” da una macchina all’altra.
Di seguito cercherò di illustrare brevemente quelli che a mio avviso sono i concetti salienti dei microservices, come questi si applicano e come alterano la progettazione del software.
Componibilità
Tutti coloro che si cimentano quotidianamente nel design e nello sviluppo di software, sanno benissimo che alla base di un qualsiasi sistema sufficientemente complesso c’è la suddivisione in parti delle funzionalità del sistema anche dette moduli, componenti o librerie a seconda del contesto. Ogni parte offre funzionalità specifiche che possono essere utilizzate all’interno dell’insieme più generale che è poi il nostro applicativo finale. Il modo in cui organizziamo, controlliamo e componiamo le parti ci permette di ottenere un risultato finale più complesso e più ricco delle singole parti messe insieme.
In generale, nelle applicazioni monolitiche un componente o una libreria è prima di tutto rappresentata da un artefatto, un file, che contiene i sorgenti della libreria e che al momento della compilazione o dell’esecuzione viene opportunamente linkato al resto del progetto per poter essere fruibile all’interno del flusso esecutivo. Tralasciando gli aspetti di importazione dinamica delle librerie che non alterano il principio di fondo che sto per illustrare, la caratteristica che è sempre soddisfatta è quella di incamerare il codice della libreria all’interno del codice da noi sviluppato, così da ottenere come risultato finale un unico codice eseguibile, monolitico.
Figura 1 – L’applicativo monolitico.
È chiaro che in uno scenario di questo tipo il malfunzionamento di una singola libreria potrebbe compromettere il funzionamento di tutto l’applicativo, così come la modifica di una di esse comporta necessariamente la ricompilazione di tutto l’applicativo.
L’applicativo a microservizi
In uno scenario a microservizi, l’architettura finale è molto simile a quella monolitica appena illustrata ma diversa nella sua essenza. Nella figura 2 riportiamo quello che sarebbe lo stesso sistema formato da un applicativo unico che fa uso di tre librerie Lib A, Lib B e Lib C, in uno scenario a microservizi.
Figura 2 – Lo scenario a microservizi (µS).
Dove sono le differenze e dove sono le similitudini? In questo caso le librerie invece che essere artefatti software da importare e linkare ai nostri sorgenti sono dei veri e propri microservizi eseguiti in modo autonomo e indipendente uno dall’altro: μS A, μS B, μS C. Tali microservizi vengono richiamati all’occorrenza dall’applicativo principale qui chiamato μS Main, anch’esso un microservizio, anch’esso eseguito in modo autonomo ed indipendente dagli altri. In entrambi i casi esiste certamente una relazione di dipendenza tra il codice dell’applicativo principale e quello delle librerie; ma, nel primo caso, la relazione di dipendenza avviene tramite uno scambio di dati in memoria, mentre nel secondo caso il tuto si esprime attraverso uno scambio di messaggi via rete tra i microservizi (Main con A, B e C).
Riusabilità
Dalle proprietà di componibilità discendono diverse proprietà per quanto concerne la riusabilità dei componenti. Si considerino per esempio due applicativi diversi A e B che utilizzano entrambi le stesse librerie.
Figura 3 – Applicativi monolitici che usano le stesse librerie.
Nel caso monolitico, gli applicativi utilizzano istanze diverse di sorgenti uguali. Questo significa che un cambiamento nel sorgente di un componente comporterà una ricompilazione di tutti gli applicativi che ne fanno uso.
Figura 4 – Con i microservizi, si usano le stesse istanze per applicativi diversi.
Nel caso a microservizi invece le istanze dei microservizi utilizzati sono le stesse per entrambi gli applicativi. Questo significa che un cambiamento di codice di un microservizio si propaga immediatamente a tutti coloro che lo utilizzano.
Scalabilità
Sempre dalle proprietà di componibilità discendono quelle relative alla scalabilità.
Figura 5 – I microservizi hanno il loro positivo effetto anche quando si tratta di scalabilità.
Semplicemente osservando la figura 5, si comprende la differenza tra cosa significa scalare un sistema monolitico e farlo con un sistema distribuito. Nel primo caso tutto il sistema va replicato e bilanciato dipendentemente dal carico, mentre nel secondo caso vengono replicati e bilanciati solamente i microservizi che necessitano.
Deployment
Anche per quanto concerne il deployment degli applicativi la differenza salta all’occhio semplicemente osservando la figura 6.
Figura 6 – Il deployment è più flessibile con i microservizi.
Nel caso dell’applicativo monolitico, ovviamente non c’è molta scelta se non quella di effettuare il deployment su una macchina dedicata. Contrariamente, nel caso dei microservizi, il deployment può essere realizzato sia su una stessa macchina che distribuito su più macchine dipendentemente dai requisiti di performance.
Monitoring
Un tema molto importante è quello del monitoring e del debugging degli applicativi. Nel caso monolitico generalmente l’applicativo genera dei file detti di log al fine di segnalare malfunzionamenti o attività particolari dell’applicativo. In taluni casi l’applicativo stesso è dotato di un’interfaccia in grado di consultare questi log.
Per quanto concerne un sistema a microservizi il concetto di monitoring deve necessariamente essere esteso. Parallelamente a un monitoring di sistema che può essere effettuato con prodotti già presenti sul mercato, diventa necessario anche monitorare i flussi e lo scambio di messaggi tra i diversi microservizi. Il tema è ancora oggetto di discussione e ci sono diverse modalità per affrontare il problema. Qui di seguito propongo la soluzione che generalmente adottiamo in italianaSoftware [2] per i nostri sistemi.
Figura 7 – I microservizi richiedono l’adozione di soluzioni adeguate per monitorare non solo il sistema ma anche lo scambio di messaggi e i flussi.
Come si può notare, il logging delle attività viene risolto a livello architetturale introducendo un ulteriore microservizio in grado di raccogliere tutte le attività provenienti dai vari microservizi.
Cloud
La mia opinione è che l’avvento dei microservizi sia profondamente collegato all’adozione e alla diffusione del cloud computing. Il tema essenziale che viene introdotto dal cloud è infatti proprio quello del deployment degli applicativi che vengono ospitati sulle macchine del fornitore di servizio cloud senza che il cliente finale sappia dove si trovano.
La spinta del cloud come supporto standard per il deployment di applicativi porta necessariamente a ripensare il modo con il quale essi vengono progettati e sviluppati. I microservizi sono il modo nuovo e ideale per affrontare lo sviluppo di applicativi orientati nativamente al cloud computing. In effetti, se consideriamo quanto già abbiamo detto sul tema deployment, la figura 8 di fatto non riporta altro che lo stesso scenario con la semplice differenza che al posto della macchina reale abbiamo una “nuvola”.
Figura 8 – Con l’affermazione del cloud come “supporto” standard per il deployment di applicativi, i microservizi sono la conseguenza naturale.
Il mercato
Infine, vediamo come potrebbe cambiare il mercato del software e in generale il mercato degli applicativi. Il mercato del software è caratterizzato fondamentalmente da due segmenti: quello dei prodotti e quello dei servizi. Qualora il modello dei microservice dovesse affermarsi con decisione come paradigma di riferimento per lo sviluppo del software, il primo dei due segmenti, quello dei prodotti, potrebbe subire una modifica non irrilevante.
Il concetto di prodotto software è collegato all’idea di sviluppare un applicativo in grado di rispondere a un insieme di funzionalità collegate a un area precisa di problemi. Si pensi ad esempio ai prodotti per CMS oppure ai prodotti per l’archiviazione documentale, e così via. Siccome devono essere appetibili a un mercato ampio, di solito i prodotti tendono ad essere sviluppati per coprire un insieme più vasto possibile di esigenze relativamente a una data area di lavoro: questo implica che nei prodotti c’è spesso un numero elevato di funzioni che potrebbero servire, ma che poi molti utenti che acquistano quel prodotto non useranno mai nella realtà. In pratica, i clienti in genere acquistano un insieme di funzionalità in eccesso rispetto a quelle di cui hanno realmente bisogno pagando il servizio per customizzare il prodotto sulle proprie esigenze.
Figura 9 – L’architettura a microservizi consente al cliente di scegliere e acquistare solo le funzionalità di cui ha bisogno, scegliendo dagli scaffali.
Se il modello di sviluppo orientato ai microservizi dovesse prendere piede in forma massiva e capillare, allora il cliente andrebbe alla ricerca solamente del set minimo di funzionalità di cui ha veramente bisogno. Andrebbe alla ricerca del microservizio, o dei microservizi, che servono a soddisfare le sue esigenze.
Nella figura 9 cerco di mostrare questa intuizione mettendo a sinistra il modello attuale e a destra quello ipotetico futuro a microservizi. Nel caso attuale attorno al prodotto si possono sviluppare aziende intere le quali si occupano dello sviluppo, della manutenzione, della commercializzazione e dei servizi post vendita. L’idea è quella che c’è un negozio per ogni prodotto. Nello scenario a microservizi, l’idea si avvicina più a quella di un grande supermercato che espone tutti i possibili microservizi che si potranno utilizzare sia in SaaS che in locale, acquistandone gli eseguibili. Sarà il cliente stesso, o chi collabora con lui, a comporre i microservizi a seconda delle sue necessità ed esigenze.
Che cosa ci attende realmente con i microservices?
I microservices sono al momento oggetto di intenso dibattito in rete. C’è chi sostiene siano l’ennesima “buzzword”; e c’è chi, come me, ritiene invece che siano una vera e propria rivoluzione. La mia propensione per la seconda ipotesi piuttosto che per la prima nasce dall’osservazione di alcuni fenomeni che, tra loro combinati, mi portano a dedurre che nei prossimi anni assisteremo a un crescente utilizzo dei microservizi.
Questi fenomeni sono: consapevolezza crescente che gli scambi economici del futuro avverrano prevalentamente se non addirittura esclusivamente su Internet, necessità di avere sistemi ICT estremamente flessibili e scalabili con le necessità di business, diffusione sempre più capillare del cloud computing.
Internet come piazza del commercio
Il primo fenomeno è quello che vedrà l’affermazione totalizzante di Internet come piazza privilegiata per il commercio, qualsiasi tipo di commercio. Nonostante la diffusione sempre più capillare della rete infatti, siamo ancora in una fase di transizione dove il commercio tradizionale si unisce a quello digitale. Ritengo che il secondo sia destinato a prevalere e se ciò è vero, sarà obbligatorio per tutti avere una piattaforma ICT, non importa se minimale, con la quale operare all’interno della piazza economica mondiale e locale. Da qui il bisogno primario di essere opportunamente equipaggiati con una infrastruttura software adeguata.
Necessità di sistemi ICT flessibili e scalabili
Il secondo fenomeno è legato al fatto che per sua natura la rete è liquida e mutevole, è fortemente dinamica e i suoi “umori” cambiano in fretta. Questo significa che per cavalcarne le onde sarà necessario dotarsi di strumenti rapidi, flessibili e scalabili. Ciò che funziona molto bene oggi forse non funzionerà molto bene domani e viceversa. Per questo motivo gli investimenti dovranno essere commisurati e proporzionati al livello di business generato e, sempre per questo motivo, le piattaforme software dovranno seguire, in termini di costi gestionali, gli andamenti del business sviluppato.
L’affermazione del cloud computing
Infine vi è la diffusione sempre più importante del cloud computing. Proprio per cercare di rendere scalabili i costi di infrastruttura con il livello di business generato, la prima risposta tecnologica che offre queste opportunità è proprio il cloud computing dove il costo infrastrutturale del software viene spalmato annualmente con l’acquisto di soluzioni in SaaS così da ridurre gli impegni e gli investimenti infrastrutturali interni per spostarli sull’esterno. Il cloud è perciò la risposta infrastrutturale alle prime due esigenze che tuttavia, oltre ad offrire effettivamente queste opportunità, offre anche dei vincoli e dei pericoli.
Il più elevato di tutti è quello del vendor lock-in. Sì, perche’ se è pur vero che posso acquistare a prezzo ridotto una licenza per un software SaaS che risiede chissà dove, è altrettanto vero che, nella stragrande maggioranza dei casi, non posso accedere ai e visionare i dati di questo software, ne’ posso gestirli a mio piacimento; così come non ho la possibilità di entrare nel merito di molti flussi e processi che però mi riguardano. Non ho perciò accesso a parti del sistema che potrebbero essere per me di estrema importanza. L’anello mancante della catena è perciò proprio il mondo applicativo.
Ciò che serve è un modo flessibile ed efficace per creare, spostare e ridefinire i propri processi nel cloud; in altri termini, il bisogno è quello di avere la libertà totale di gestire i proprio processi e i propri dati.
Conclusioni
Abbiamo visto le caratteristiche di una architettura basata sui microservices e le differenze con il tradizionale modello basato su applicativi monolitici. I microservizi offrono indubbi vantaggi e possono davvero configurarsi come una rivoluzione nel mondo ICT. I microservices sono l’ultimo anello di una catena evolutiva dello sviluppo del software che si è messa in atto dall’arrivo di Internet e che va di pari passo con l’affermazione del cloud computing.
Accanto ai molti vantaggi insiti in questo stile architetturale, esistono anche alcuni “pericoli”, legati più che altro ad alcuni connaturati nell’attuale modalità con cui i vendor gestiscono i loro servixi di cloud. Per questo motivo, oltre al fatto che diventerà essenziale capire le funzionalità e i dati di cui abbiamo bisogno, diventerà altresì essenziale avere un modus operandi concreto per farlo, e farlo velocemente.
Il centro del proprio agire nella rete saranno le architetture software: esse saranno i nostri piedi, le nostre mani e la nostra testa nell’arena di Internet.