{"id":6828,"date":"2024-03-29T09:00:00","date_gmt":"2024-03-29T08:00:00","guid":{"rendered":"https:\/\/blog.besharp.it\/?p=6828"},"modified":"2024-03-29T10:13:14","modified_gmt":"2024-03-29T09:13:14","slug":"strategie-di-decoupling-single-queue-o-una-coda-per-microservizio","status":"publish","type":"post","link":"https:\/\/blog.besharp.it\/it\/strategie-di-decoupling-single-queue-o-una-coda-per-microservizio\/","title":{"rendered":"Strategie di Decoupling: single-queue o una coda per microservizio?"},"content":{"rendered":"\n
Il disaccoppiamento dei carichi di lavoro complessi \u00e8 una pratica che le persone talvolta intraprendono senza una chiara comprensione dei vantaggi e dei rischi. <\/p>\n\n\n\n
Sentiamo spesso parlare di applicazioni modulari, costruite con microservizi, dove \u00e8 possibile decidere cosa attivare o disattivare senza alcun impatto sulle altre parti, o che possono scalare all’infinito. <\/p>\n\n\n\n
Tuttavia, quali sono le pratiche da utilizzare per il monitoraggio? Esiste il rischio di finire per lavorare in un ambiente disordinato che, per il bene dello scaling e di tutti gli altri vantaggi, rovina l’esperienza dello sviluppatore? Seguendo questo link troverete un ottimo articolo<\/a> scritto dal mio collega e amico, Damiano, che approfondisce le considerazioni che tutti dovrebbero fare quando lavorano con i microservizi. <\/p>\n\n\n\n Oggi discuteremo due strategie di decoupling, dei loro benefici, delle loro sfide e anche di quando una \u00e8 migliore dell’altra. Il focus sar\u00e0 sui servizi AWS perch\u00e9 ci sono molte opzioni (Amazon SQS, EventBridge, SNS), ma queste considerazioni possono essere applicate anche ad altri strumenti.<\/p>\n\n\n\n Il nome \u00e8 piuttosto autoesplicativo: il nostro carico di lavoro ha un unico punto di ingresso per lo scambio e la lettura dei messaggi. Ogni produttore di eventi invia il suo payload a quella coda, dove sono in ascolto pi\u00f9 consumatori. Questo approccio viene spesso respinto come troppo caotico poich\u00e9 la coda contiene messaggi non correlati e non si allinea con una mentalit\u00e0 “orientata ai microservizi”. <\/p>\n\n\n\n Anche se questo potrebbe essere vero: i vantaggi esistono e non dovrebbero essere trascurati. <\/p>\n\n\n\n Immagina di lavorare su un’applicazione in cui abbiamo molti produttori di eventi e solo alcuni processi che elaborano quei messaggi. Quando il numero di tipi di eventi \u00e8 piccolo, un approccio a coda singola \u00e8 davvero facile da implementare, monitorare ed estendere. Ogni volta che viene creato un nuovo produttore, esso dovr\u00e0 semplicemente inviare messaggi all’unica coda esistente. D’altra parte, i consumatori dovranno filtrare i messaggi per tipo per gestire solo gli eventi all’interno della propria competenza, il che richiede un po’ pi\u00f9 di logica da implementare. <\/p>\n\n\n\n Questo \u00e8 un approccio molto pi\u00f9 semplice per la costruzione di un’applicazione disaccoppiata, ma, come detto in apertura di questo articolo, non dovremmo mai iniziare con la complessit\u00e0. <\/p>\n\n\n\n Ci\u00f2 che \u00e8 determinante \u00e8 la consapevolezza dei picchi di traffico a cui la coda potrebbe essere sottoposta; avere troppi messaggi che passano attraverso lo stesso tunnel potrebbe creare congestione.<\/p>\n\n\n\n Mentre l’approccio a coda singola \u00e8 ideale per carichi di lavoro ridotti, un’applicazione pi\u00f9 complessa con pi\u00f9 persone al lavoro \u00e8 pi\u00f9 facile da mantenere se ogni microservizio ha la sua coda dedicata. Ci\u00f2 consente un monitoraggio pi\u00f9 dettagliato poich\u00e9 pu\u00f2 essere effettuato a livello di microservizio e i messaggi che attraversano la coda seguiranno uno standard. Questa strategia consente anche di creare una gestione pi\u00f9 dettagliata delle autorizzazioni: se desideri stabilire una comunicazione tra due microservizi, dovrai concedere l’accesso al produttore per generare eventi all’interno della coda del consumatore. <\/p>\n\n\n\n Sii consapevole che, ogni volta che uno dei tuoi microservizi genera eventi per un altro microservizio, nasce una dipendenza, creando quindi un antipattern. <\/strong><\/p>\n\n\n\n I microservizi dovrebbero essere indipendenti l’uno dall’altro, dovrebbero avere il proprio database, le proprie risorse computazionali e non dovrebbero comunicare tra loro. Questa \u00e8 la teoria naturalmente; nel mondo reale dobbiamo analizzare ogni singolo caso per capire se attenerci ai modelli comuni, o se deviare da uno standard pu\u00f2 aiutarci a creare flussi di lavoro pi\u00f9 facili da capire. <\/p>\n\n\n\n In ogni caso, una buona strategia per gestire flussi di lavoro complessi in cui \u00e8 necessario chiamare pi\u00f9 microservizi pu\u00f2 essere quella di impostare macchine a stati<\/strong> che gestiscano in modo controllato l’inoltro degli eventi, l’analisi degli output e la presa di decisioni. Ci\u00f2 rende la nostra applicazione facile da debuggare, monitorare ed estendere con nuovi microservizi (in quanto \u00e8 sufficiente che seguano lo standard definito). Se rendi i tuoi microservizi davvero indipendenti l’uno dall’altro, sarai anche in grado di testarli senza creare effetti collaterali.<\/p>\n\n\n\n Abbiamo gi\u00e0 citato il tema del monitoraggio due volte in questo articolo. \u00c8 il momento di analizzarlo meglio. Quando si lavora con i microservizi, di solito si creano comunicazioni asincrone tra di essi ed \u00e8 spesso difficile tenere traccia del ciclo di vita di un evento specifico: se qualcosa va storto, dobbiamo essere in grado di capire quale processo \u00e8 fallito, come dovremmo rimediare all’errore e come possiamo prevenire effetti collaterali che possono incidere sull’esperienza dell’utente. Questo \u00e8 un argomento che i DevOps devono analizzare approfonditamente nella prima fase del progetto. <\/p>\n\n\n\n Su AWS, strumenti come le dashboard di CloudWatch<\/strong> possono essere davvero utili per ottenere informazioni su come si comporta il carico di lavoro, ma bisogna andare oltre. <\/p>\n\n\n\n Naturalmente, avere la possibilit\u00e0 di monitorare il numero di messaggi all’interno della coda o il numero di eventi che non sono riusciti a essere elaborati \u00e8 importante per capire dove si trovano i single-point of failure<\/em> e dove dovremmo considerare lo scaling, ma abbiamo comunque bisogno di qualcosa che ci aiuti a monitorare il carico di lavoro a livello di applicazione. <\/p>\n\n\n\n Ecco dove AWS X-Ray pu\u00f2 aiutarci: AWS X-Ray ci consente di tracciare e analizzare le richieste mentre viaggiano attraverso la nostra applicazione. Questo ci fornisce una visione dettagliata del suo comportamento, consentendoci di identificare dove si verificano i colli di bottiglia e quali servizi causano ritardi. Questa visione end-to-end del flusso di lavoro ci consente di identificare e risolvere i problemi in modo pi\u00f9 efficace. Con X-Ray possiamo ottenere metriche utili come il tempo impiegato dal nostro microservizio per fare qualcosa (come una richiesta HTTP) o quali altri microservizi sono stati chiamati per elaborare un evento.<\/p>\n\n\n\n Quando parliamo del disaccoppiamento dei processi, il primo servizio AWS che ci viene in mente \u00e8 Amazon SQS. \u00c8 stato creato proprio con questo scopo: i produttori possono inserire i loro eventi all’interno di una coda mentre i consumatori effettuano il polling su quella coda per vedere se ci sono dei messaggi da elaborare. Amazon SQS offre diverse funzionalit\u00e0 che possono essere utili per il nostro obiettivo, come le dead-letter queue <\/em>per i messaggi non elaborati, long-polling<\/em> per evitare sul lato del consumatore di inondare la coda con richieste che non produrranno nessun output, e code FIFO se abbiamo bisogno di elaborare i nostri eventi nell’ordine in cui sono stati prodotti. <\/p>\n\n\n\n Amazon SQS \u00e8 un ottimo servizio, ma possiamo trovare in altri servizi AWS delle funzionalit\u00e0 che possono soddisfare meglio le nostre esigenze. Un servizio AWS che mi piace particolarmente \u00e8 Amazon EventBridge. Con Amazon EventBridge possiamo registrare pi\u00f9 destinazioni per essere notificati ogni volta che viene pubblicato un messaggio in un bus degli eventi, ma possiamo anche filtrare questi messaggi specificando dei pattern per inoltrarli alla destinazione corretta. Questo \u00e8 davvero utile se stiamo costruendo un approccio a coda singola!<\/p>\n\n\n\n <\/p>\n\n\nStrategia 1: approccio a coda singola<\/h2>\n\n\n\n
Strategia 2: approccio con coda dedicata ai microservizi<\/h2>\n\n\n\n
Parliamo di monitoraggio<\/h2>\n\n\n\n
Servizi AWS per il disaccoppiamento<\/h2>\n\n\n\n
<\/figure><\/div>\n\n\n