• Non ci sono risultati.

Il nostro sistema introduce nuove migliorie ed elasticità per gli sviluppatori e le aziende che vogliono innovare i loro strumenti per una produzione software di qualità più alta, ma lascia molto spazio ad ancor più nuove tecnologie dedite a rendere dinamico l’approccio dell’organizzazione e gestione delle problematiche dovute a vincoli strutturali. Tra questi sono elencati li ad esempio: errori ricorrenti dovuti a indisponibilità di un determinato servizio/database, difficoltà a tenere traccia nei file di configurazione dei servizi puntati da altri suoi dipendenti, etc..

9.1

Circuit Breaker Pattern

Il circuit breaker pattern è una metodologia di sviluppo dedita alla prevenzione e monitor- aggio della “salute” di determinate chiamate remote, come database o servizi esposti. Un sistema basato interamente su chiamate remote è più soggetto a errori, in quanto quelle chia- mate potrebbero non venire accolte per un qualsiasi motivo di disservizio. Se sono chiamate particolarmente frequenti, effettuate da più di un componente del sistema, si può rischiare un degrado massiccio delle funzioni, e quindi a un grosso disservizio. L’idea di base di questa metodologia è quella di un salvavita elettrico: al fine di proteggere l’intero sistema, se una determinata sezione ha un malfunzionamento che supera una certa tolleranza specifica, il sal- vavita salta e stacca la componente, in modo che l’intero sistema non collassi o si danneggi. In termini di architettura software, si avvolgono delle funzioni di valore critico per il sistema intorno a un proxy salvavita, che monitora lo stato di salute delle chiamate effettuate. In caso di ripetuti malfunzionamenti, superata la soglia il salvavita scatterà e risponderà subito con un errore alla chiamata, prevenendo l’accumulo di traffico su una risorsa in una fase problematica del suo funzionamento. Questi proxy salvavita è bene affiancarli a degli stru- menti di allertamento, così da ottenere un immediato avviso di malfunzionamenti critici. Una volta che il problema è sistemato, tramite l’analisi della salute della chiamata, il salvavita si può autoresettare. Per esemplificare, pensiamo a una chiamata al Database da parte di uno dei nostri servizi, ma il pod risulta particolarmente occupato e non riesce a gestire tutte le chiamate che gli vengono fatte, quindi inizierà a generare dei timeout in quanto il servizio

non risponde. Avvalendosi del pattern sopracitato, possiamo incapsulare le chiamate al DB in un proxy che sorveglia la salute della comunicazione. Rilevata l’anomalia, il salvavita scatta e impedisce ulteriori chiamate che affollerebbero soltanto il pod già occupato, fino a un possibile crash completo. L’impedimento delle chiamate sarà accompagnato da un errore esplicito verso il servizio che farà capire all’utente il disservizio. L’impedimento delle chia- mate può essere in questo esempio cruciale per mantenere il sistema in fase stabile, in quanto impedisce il crash dovuto all’affollamento del pod, e da la possibilità al malfunzionamento di risolversi da solo, in quanto il timeout è dovuto semplicemente allo stato di indaffara- mento del database, e non da malfunzionamenti catastrofici come totale down funzionale di quest’ultimo. Il salvavita accompagnato poi da meccanismi di allertamento, aiutano gli sviluppatori/manutentori all’identificazione e risoluzione celere dell’anomalia.

9.2

Service Discovery

Al tempo dello sviluppo del progetto, gli endpoint dei microservizi sono stati inseriti in maniera “hardcoded” ossia scritti più o meno esplicitamente nel codice sorgente. Questo rende difficile e inefficiente la configurazione nei confronti della comunicazione tra mi- croservizi dipendenti nello stesso sistema. Per sopperire a questa difficoltà, esistono tec- nologie chiamate di Service Discovery, che possiamo definire un censimento automatico dei servizi conosciuti in un sistema. Il funzionamento consiste essenzialmente in un registro centrale a cui i microservizi di uno stesso sistema si iscrivono autonomamente con una certa logica, che poi è interrogabile da tutti gli altri microservizi per conoscere il nome del servizio cercato. In questo modo il puntamento dell’endpoint risulta dinamico e in caso di un nuovo servizio aggiunto al sistema non si dovrà rivisitare la configurazione di tutti i microservizi che ne abbiano bisogno, ma basterà implementare la logica per interrogare il registro centrale. Si potrebbe pensare che questo introduca un ulteriore grado di complessità, ossia che per ogni interrogazione a un microservizio, sia necessario fare una chiamata remota al registro per poi effettuare veramente la chiamata. Questo risulta invece irrisorio, in quanto anche questo registro può essere implementato come un microservizio all’interno della piattaforma Open- shift, che sfruttando le potenzialità del cloud rende trascurabile l’impatto della chiamata sulla logica di funzionamento del resto del servizio.

10

CONCLUSIONI

Il metodo di sviluppo monolitico è uno dei più diffusi e comuni nel campo dello sviluppo software ed è comunque una valida scelta, nel giusto campo di applicazione. Per applica- tivi di contenute dimensioni e progetti evolutivi, è una scelta più che saggia e anzi alta- mente consigliata. L’infrastruttura a microservizi invece, è più proiettata al lungo termine, all’evoluzione repentina, elasticità e manutenzione per sviluppi di grosso taglio. Per ap- plicativi di piccole dimensioni il costo di pianificazione e organizzazione è molto più alto della sua controparte monolitica. Si può concludere che in ambito enterprise l’architettura a microservizi porta un grosso vantaggio in termini di sviluppo e costi, rendendo la versione monolitica una scelta altamente sconsigliata.

Bibliography

[1] Ola Mustafa, GranMicro: A Black-Box Based Approach for Optimizing Microservices Based ApplicationsFrom Science to Society ,pp 283-294

[2] Sourabh Sharma, Rajesh RV, David Gonzalez, Microservices: Building Scalable Soft- ware

[3] Spring, https://spring.io/

[4] Spring boot, https://spring.io/projects/spring-boot

[5] Mockito, https://static.javadoc.io/org.mockito/mockito-

core/2.27.0/org/mockito/Mockito.html

[6] Documentazione e Schema nodo Kubernetes, https://kubernetes.io/docs/tutorials/kubernetes- basics/explore/explore-intro/

[7] Spring Data JPA, https://docs.spring.io/spring-data/jpa/docs/2.1.6.RELEASE/reference/html/ [8] Maven, Building java projects with Maven, https://spring.io/guides/gs/maven/

[9] Junit, User guide, https://junit.org/junit5/docs/current/user-guide/

[10] Sam Newman, Building Microservices - designing fine-grained systems [11] Hibernate ORM, https://hibernate.org/orm/documentation/5.4/

[12] PostgreSQL documentation, https://www.postgresql.org/docs/11/index.html

Indice

Documenti correlati