X
    Categories: blog

Why Microservices

In genere quando si parla di microservizi si pensa principalmente alla scalabilità. Giusto, è corretto, ma forse non è il solo elemento da considerare per la scelta di una architettura a microservizi.

Netflix e Amazon hanno fatto grandi cose sulle architetture dei microservizi, ma quante aziende nel mondo possono paragonarsi a Netflix o Amazon?

O meglio: quante aziende conoscete che hanno gli stessi requisiti di scalabilità di Netflix o Amazon?

La risposta è che la stragrande maggioranza degli sviluppatori si occupa di software applicativi aziendali, con un ordine di scalabilità relativamente piccolo.

Quindi, per la maggioranza di noi sviluppatori, i microservizi di solito non riguardano, se non in second’ordine, la scalabilità.

Bòn!

Perché utilizzare i microservizi

Quello che normalmente ci assilla, invece, è cercare di migliorare sempre di più i tempi di consegna delle nostre release, e in effetti le architetture a microservizi hanno tra gli obiettivi anche quello di velocizzare i tempi di produzione, soprattutto per la fase di gestione ed evoluzione di un sistema.

…un momento… ma per fare questo non c’è già DevOps? … quindi perché scomodare i microservizi per raggiungere questo scopo?

C’è un motivo se questi due temi sono strettamente intrecciati e complementari.

Immaginiamo per un momento di avere un team di sviluppo molto grande e, al contempo, di avere una base di codice così estesa che sia estremamente difficile cambiare qualsiasi cosa senza incasinare una dozzina di punti diversi di una applicazione monolitica… se non fate fatica ad immaginarlo, siete nella condizione giusta… bene.

Il coordinamento del lavoro tra persone che condividono una base di codice ampia, strettamente accoppiata e aggrovigliata, è estremamente complesso.

Con l’uso dei microservizi, si mira a cercare di dividere in parti più maneggevoli questa enorme codebase monolitica, producendo artefatti più piccoli, ben definiti, coesi e liberamente accoppiabili.

…chiameremo ognuna di queste piccole parti “microservizio”.

Si tratta quindi di identificare alcune aree della nostra codebase che in modo “naturale” evolvono insieme, e separarle componendo un artefatto che può essere rilasciato indipendentemente dagli altri artefatti.

Qualunque sistema ben strutturato probabilmente è già più o meno frammentato in librerie, quindi perché complicarsi la vita?

…un attimo, andiamo per gradi e mettiamo sul tavolo qualche altra considerazione.

Microservizi e DevOps

Non c’è maggiore frustrazione per gli sviluppatori che vedere ciò che hanno costruito rimanere inattivo in un repository per mesi prima di entrare in produzione; peggio ancora se guardiamo questa cosa dal lato del cliente finale.

Vogliamo produrre software in modo sempre più veloce e più sicuro perciò dobbiamo individuare le ragioni che ci impediscono di farlo; purtroppo, l’esperienza insegna che la ragione numero uno sono i bug.

Non forniamo il software più velocemente perché ognuna delle nostre versioni software è affetta da molti bug in produzione.

La prossima domanda è: cosa provoca bug nella produzione?

Non è una domanda semplice, ma la risposta più sintetica (e forse banale) è: la causa degli errori nella produzione di una versione di codice è che la modifica è un’attività complessa, sia riguardo alle modifiche fatte al codice sorgente, che alla configurazione dell’ambiente operativo.

…ovvero, quando cambiamo le cose, i sistemi complessi tendono a cadere a pezzi!

Ovviamente non possiamo usare questa affermazione come una scusa per non cambiare… il cambiamento fa parte dei cicli di vita di ogni cosa.

Proviamo perciò a ragionare sulla semplice correlazione tra modifiche e bug.

Più modifiche abbiamo in ciascuna delle nostre versioni, più bug abbiamo nella produzione… più stravolgiamo – per qualsiasi motivazione funzionale – parti di codice, più è probabile che si creino o propaghino errori in porzioni dell’applicazione che ritenevamo esenti dalle modifiche effettuate.

Il modo tradizionale di provare a risolvere questo problema è avere più tempo per i test.

Se produciamo una versione ogni settimana, abbiamo bisogno di almeno due settimane di tempo complessivo per fare uscire le modifiche, perché abbiamo bisogno di test mirati, la cui costruzione spesso non è banale.

Se forniamo versioni ogni mese, necessitiamo di due mesi complessivi e così via.

Non è difficile immaginare che prima o poi alcuni team distribuiranno software in produzione solo annualmente.

Perciò, questo approccio è in qualche misura anti-economico, inefficiente ed inefficace.

Un approccio che può garantire un migliore risultato economico per la fornitura di software, al fine di avere meno bug nella produzione, è l’opposto: dobbiamo consegnare più spesso.

Se consegniamo più spesso, stiamo anche implicitamente riducendo la quantità di cose che cambiano tra una versione e la successiva.

Quindi meno cose cambiamo tra le versioni, meno è probabile che la nuova versione causi errori nella produzione.

E se abbiamo ancora bug in produzione, anche se abbiamo modificato solo alcune decine di righe di codice, dove può essere la fonte di questi bug?

Più piccole sono le modifiche, più facile è individuare l’origine dei bug.

Perciò è anche più facile risolverli.

Il termine tecnico utilizzato in DevOps per caratterizzare la quantità di modifiche che abbiamo tra ogni versione del software è chiamato batch size.

Quindi, se dovessimo coniare un solo principio per il successo del modello DevOps, sarebbe questo: <ridurre la batch size alla dimensione minima consentita che è possibile gestire>.

Per farlo, è necessaria una pipeline di distribuzione del software completamente automatizzata, tipicamente basata su componenti isolate in quelli che tipicamente sono chiamati Container, tecnologia che abilita il modello di sviluppo a Microservizi.

Ecco quindi dove i processi (DevOps) e gli strumenti (Microservizi) si incrociano per formare un quadro unico.

Possiamo migliorare i tempi di consegna e le dimensioni di ogni lotto prodotto perché non avremo bisogno di aspettare che gli altri pezzi siano “pronti”, perché le architetture a microservizi sono composte da più artefatti, ognuno dei quali, se rispettiamo certe regole, può essere liberamente distribuito in produzione, consentendoci di modificare le funzioni del nostro microservizio e passarlo in produzione senza preoccuparci di “rompere” altre cose.

Come cambia la progettazione

Le note dolenti sono che nulla, purtroppo, viene gratis. I sistemi distribuiti – e le architetture a Microservizi sono un caso evidente di sistema distribuito – sono difficili da gestire.

Per gestire una qualsiasi architettura a microservizi, un requisito assoluto è essere in grado di avere una pipeline di distribuzione del software molto matura.

Alcuni indicatori che si possono utilizzare per valutare il grado di maturità della pipeline sono la quantità di intervento manuale richiesto, la quantità di test automatici, il provisioning automatico degli ambienti e il monitoraggio.

Quando abbiamo a che fare con i microservizi, dobbiamo essere consapevoli del fatto che avremo bisogno di affrontare un’intera nuova serie di problemi che i sistemi distribuiti mettono sul tavolo.

Tracciatura, monitoraggio, aggregazione dei registri e resilienza sono alcuni dei problemi di cui non dobbiamo preoccuparci quando lavoriamo su un monolite.

Le architetture dei microservizi hanno un costo elevato, che vale la pena pagare se i problemi nell’approccio monolitico ti costano di più.

Il grafico che segue cerca di esemplificare i casi in cui sia più o meno conveniente utilizzare un approccio monolitico o a Microservizi:

Negli articoli che seguono approfondiremo sia le tecnologie che le modalità di design delle applicazioni a Microservizi, entrando nel dettaglio sia delle problematiche che queste pongono in termini di design, produzione e strutturazione architetturale, ma anche degli enormi vantaggi che queste portano in termini di manutenibilità e di potenziale evolutivo.

Dicevo, che possiamo ipotizzare che il perimetro funzionale di un microservizio sia legato ad un insieme di funzioni che tipicamente evolvono assieme…. alcuni invece ne parlano in termini di “modulo funzionale”, altri ancora sostengono una buona metrica per stabilire la dimensione di un microservizio sia la quantità di codice che un team riesce a sviluppare in 10-15 giorni, o in uno sprint.

Nei fatti non esiste una vera e propria regola, questi sono tutti esempi che servono solamente a rendere l’idea della granularità, che poi ogni progettista deve applicare al proprio contesto, anche in funzione dei vincoli operativi con cui deve fare i conti di volta in volta.

A questo punto, però, un progettista di software, che abbia alle spalle un’esperienza discreta nella realizzazione di applicazioni monolitiche, tipicamente ha una domanda… che ha trattenuto fino a questo punto, ma che non riesce più ad evitare:

Ma in che modo devo modificare il mio database monolitico per lavorare a microservizi?”

L’attitudine principale che è necessario acquisire, è quella di imparare a modellare le componenti informative in silos isolati, allo stesso modo in cui si isolano le component funzionali, e quindi muoversi in una logica di Decentralized Data Management.

Per fornire alla precedente domanda una risposta tramite un singolo concetto base, potrei dire semplicemente:

Ogni microservizio deve avere la propria base dati autonoma”

– Gelo –

…in effetti questo concetto porta con sè numerose implicazioni metodologiche e tecnologiche, oltre ad una serie di sfide non propriamente agevoli da superare per mantenere consistenza ed integrità del sistema.

t.b.c.

Alcuni riferimenti interessanti per iniziare ad approfondire il tema:

https://www.martinfowler.com/articles/microservices.html

Creare una applicazione basata su una architettura a microservizi è un percorso piuttosto irto di difficoltà, molte delle quali risultano nuove per la gran parte degli sviluppatori.

In questo stesso blog troverete via via approfondita la questione da vari punti di vista:

  1. come approcciare il project management di un progetto DevOps,
  2. come definire una piattaforma tecnologica orientata ai microservizi,
  3. come affrontare l’analisi di un prodotto a microservizi, o come rimodellare un monolite.
Andrea Montefiori: Informatico da sempre, appassionato di scienza e tecnologia. Mi sono districato tra le schede perforate e i nastri dei mainframe anni ’80, passando attraverso una serie di progetti e alla gestione della produzione, fino al momento in cui ho tentato di capire come si addestrano le Intelligenze Artificiali, dopo avere tentato inutilmente di addestrare il mio cane. Ho deciso che lascio fare i colleghi. Per 10 anni Direttore Tecnico in Gruppo Maggioli, sono passato alla Ricerca e Sviluppo con l’obiettivo di portare all’interno dell’azienda nuove energie, tecnologie e modelli lavorativi applicando uno splendido team a progetti innovativi con partner europei e nazionali.
Related Post