• Non ci sono risultati.

5. Microservizi

5.7 Continuous Integration e Continuous Delivery

La Continuous Integration è un elemento da considerare quando parliamo di microservizi, è un concetto relativo alla parte di sviluppo e rilascio del software, quindi quando parliamo di build, versionamento, modelli per la gestione e l’allineamento dei microservizi.

L’obiettivo della CI è mantenere i microservizi allineati tra loro e funzionanti, qundi essere certi che il rilascio di nuovo codice si integri correttamente con il codice già

31

presente rilasciato in precedenza sul repository. Un server CI controlla il codice dopo il commit e verifica che compili e che i test passino.

Come parte del processo di Continuous Integration vengono creati gli artifacts, cioè dei pacchetti che serviranno per un ulteriore validazione del codice, come passaggio aggiuntivo per il deploy di un servizio, infatti, questo viene nuovamente testato prima di essere installato sulla piattaforma relativa. Viene creato un artifact per ogni

versione del microservizio, di modo da essere certi che la versione ed il codice

installati siano quelli testati in precedenza. Questi pacchetti vengono conservati in un repository.

Gli artifacts potrebbero necessitare di tool e piattaforme di supporto. Gli OS artifacts sono i sistemi più funzionali che permettono di nascondere la tecnologia utilizzata dal microservizio.

Utilizzare la CI comporta vari benefici:

- permette di avere un feedback immediato sulla qualità del codice, quindi poter allo stesso tempo individuare eventuali parti da correggere su porzioni limitate di codice, rendendo più semplice individuare l’errore;

- permette di automatizzare la creazione di artifact binari;

- il codice è versionato quindi è possibile ricreare l’artifact.

La chiave dell’applicazione dell’integrazione continua è capire come applicarla realmente e non limitarsi ad utilizzare i tool a disposizione. Possiamo seguire queste regole:

1. Bisogna controllare la mainline una volta al giorno: bisogna essere certi che il codice sia stato integrato altrimenti avremmo codice accumulato. Bisogna integrare costantemente il codice al branch principale;

2. I cambiamenti al codice vanno validati e testati, bisogna evitare di rompere il codice e il sistema: CI senza validazione non è CI;

3. Quando una build si rompe ed il pacchetto artifact non viene creato, va messa come priorità la correzione del codice: non bisogna accumulare build

“rotte”, bisogna correggere immediatamente l’errore. Se lasciamo più build da sistemare accumuliamo gli errori ed il tempo per correggere le build aumenta.

Capito cos’è la CI bisogna capire come questo viene integrato ed applicato ai

microservizi. Ribadendo che vogliamo mantenere l’autonomia di modifica del codice e deploy di ogni microservizio, bisogna capire come mappare un microservizio in una build CI.

Sam Newman all’interno del suo libro ci presenta tre opzioni:

- avere un unico repository in cui caricare tutto il codice ed effettuare una singola build per tutto il codice, quindi un’unica CI build per tutti i

32

microservizi, ciò comporta una semplificazione del sistema di CI ma ad ogni build verranno testati anche microservizi o porzioni di codice che non lo

necessitano e ciò costituisce un costo superfluo in termini di tempo, inoltre nel caso di un fallimento della build cercare l’errore su tutto il codice sarà più complicato, infine perdiamo la possibilità di avere microservizi autonomi anche nella fase di deploy e ciò può portare ad una riduzione dei rilasci in attesa di accumulare le build nel tempo e, perciò, ad avere un sistema meno dinamico;

- una seconda opzione è avere sempre un singolo repository ma non buildare tutto il codice bensì avere un albero con un’unica sorgente da cui si diramano i blocchi di codice, in questo modo verrebbe buildata la CI del codice

interessato, da un lato resta tutto semplificato con la presenza di un unico repository di cui preoccuparsi, dall’altra si potrebbe comunque cadere

nell’abitudine di buildare e validare più servizi alla volta e quindi non il singolo microservizio, perdendo anche in questo caso dinamicità;

- la terza soluzione proposta è quella consigliata, consiste nell’avere una singola CI build per ogni microservizio, in questo modo ogni microservizio ha il proprio repository con il codice sorgente e la propria build, il che mantiene l’indipendenza del microservizio e permette di validare e testare un

microservizio alla volta, quindi avremo un singolo artifact da deployare.

Quest’ultima soluzione permette anche di avere una maggiore autonomia a livello di organizzazione dei team che lavorano sul codice, in quanto non c’è la difficoltà di dover capire chi effettua la build su tutto il codice, perché è chiaro che ogni singola build verrà effettuata dal team che ha lavorato su quel

microservizio e nel caso di grandi progetti è importante.

Quindi la soluzione migliore è avere un singolo repository per ogni microservizio e, quindi, una CI build associata ad esso.

Un argomento vicino al concetto di Continuous Integration è quello del Continuous Delivery. Nel momento in cui utilizziamo l’integrazione continua di microservizi abbiamo visto che ogni microservizio va buildato e validato, per effettuare una build abbiamo varie fasi e vari test vengono applicati per validare il microservizio. È possibile avere test veloci ed altri più lenti e che richiedono più tempo, se tutti i test venissero effettuati insieme e senza un ordine logico, potremmo cadere nel caso in cui il risultato di un test fallito ci arrivi dopo molto tempo, per questo è meglio effettuare prima i test più rapidi e, se validi, allora procedere con quelli più pesanti che

richiedono tempi maggiori. Bisogna quindi creare una pipeline della build, in cui avere più step di verifica da passare, quindi solo se tutti i test hanno un risultato positivo si procede con la build del microservizio.

Questo concetto di pipeline ci permette di tenere traccia del progresso del nostro software nei vari step, permettendoci di osservare la qualità dello stesso. La creazione

33

degli artifacts avviene sui vari step, ad ogni step validato siamo più sicuri che il codice rispetti i parametri e abbia una buona qualità.

Il CD è costruito su questi principi, nel libro di Jez Humble e Dave Farley viene sottolineato come il CD sia un approccio che permette di avere feedback costanti sulla produzione del codice. Dobbiamo creare un modello del processo che il nostro codice fa dalla validazione alla produzione. Quindi da quando viene testato a quando viene installato in produzione. Oltre ai test automatizzati sul codice e sulla sua qualità, bisogna introdurre i test manuali.

L’utilizzo di tools che supportano il CD permette di visualizzare queste pipeline e avere una visione del progresso del codice, degli step attraversati. Una volta passato uno stage e, quindi, un blocco di test, il codice viene analizzato dal successivo step che includerà altri test relativi ad altri parametri e requisiti. È possibile avere uno stadio UAT (user acceptance testing) in cui il software è testato manualmente.

Per mantenere il concetto di indipendenza visto per il CI, è bene che ogni microservizio abbia la propria pipeline.

Di base però all’inizio del progetto è possibile che il software non sia ancora grande abbastanza da necessitare più build singole, ma può essere sufficiente fare un’unica build di tutto il codice, soprattutto perché nella prima fase si hanno generalmente build frequenti su tutto il codice, questo finché non si ha una base stabile del software da cui inziare a costruire i vari microservizi.

Documenti correlati