{"id":7949,"date":"2025-07-30T15:39:17","date_gmt":"2025-07-30T13:39:17","guid":{"rendered":"https:\/\/blog.besharp.it\/?p=7949"},"modified":"2025-07-30T17:08:55","modified_gmt":"2025-07-30T15:08:55","slug":"architetture-event-driven-a-km0-dal-producer-al-consumer","status":"publish","type":"post","link":"https:\/\/blog.besharp.it\/it\/architetture-event-driven-a-km0-dal-producer-al-consumer\/","title":{"rendered":"Architetture Event-Driven a KM0: dal producer al consumer"},"content":{"rendered":"\n

Introduzione<\/h2>\n\n\n\n

In questo primo di due articoli, approfondiamo un argomento noto da tempo ma recentemente al centro di un interesse crescente: le Architetture Event-Driven ed Event-Based (EDA).<\/p>\n\n\n\n

Nonostante se ne parli sempre pi\u00f9 spesso, questo non significa che l\u2019argomento sia diventato pi\u00f9 chiaro. L\u2019obiettivo di questi articoli \u00e8 offrire una spiegazione semplice e comprensibile dei principi fondamentali alla base di questi paradigmi architetturali.<\/p>\n\n\n\n

Al centro delle EDA si trovano due ruoli principali: il Producer e il Consumer. Il Producer ha il compito di generare e inviare un messaggio. Dall’altro lato, il Consumer riceve questo messaggio e reagisce, tipicamente eseguendo una logica di business o attivando un flusso di lavoro. Questa interazione costituisce la spina dorsale del flusso informativo nelle EDA.<\/p>\n\n\n\n

La semantica degli eventi<\/h2>\n\n\n\n

Un messaggio pu\u00f2 rappresentare diversi tipi di comunicazione a seconda dell’intento del Producer. Pi\u00f9 comunemente, i messaggi si dividono in due categorie: comandi ed eventi.<\/p>\n\n\n\n

Un comando viene utilizzato quando il Producer desidera richiedere un’azione specifica al Consumer. I comandi sono tipicamente imperativi e si aspettano un certo risultato o effetto collaterale.<\/p>\n\n\n\n

Al contrario, un evento serve per notificare qualcosa che \u00e8 accaduto \u2014 spesso rappresentando un cambiamento di stato o il verificarsi di un evento di business rilevante. A differenza dei comandi, gli eventi non si aspettano una risposta diretta o un’azione da parte del Consumer.<\/p>\n\n\n\n

Questa distinzione tra comandi ed eventi \u00e8 fondamentale per comprendere come comunicano i componenti nelle EDA e influenza profondamente il modo in cui vengono progettati i sistemi.<\/p>\n\n\n\n

Canali di messaggistica<\/h2>\n\n\n\n

Un Producer sfrutta canali di messaggistica per inoltrare i messaggi verso i Consumer. Come osserva Gregor Hohpe in uno dei suoi \u201cramblings\u201d, le EDAs sono comunemente associate ai canali Publish-Subscribe (Pub\/Sub), poich\u00e9 pi\u00f9 destinatari possono essere interessati a reagire ad un singolo evento. Questo si contrappone ai canali Point-to-Point, che sono tipicamente usati per inviare comandi o documenti a un singolo Consumer.<\/p>\n\n\n\n

Nell’ecosistema AWS, questi due tipi di canali sono ben rappresentati: le code SQS rappresentano i canali Point-to-Point, mentre i topic SNS sono una chiara implementazione di canali Publish-Subscribe. Con le code SQS, ogni messaggio \u00e8 indirizzato a un solo Consumer \u2014 solitamente un worker o un’applicazione che estrae messaggi dalla coda \u2014 garantendo che venga processato una sola volta. Al contrario, i topic SNS permettono che un singolo messaggio venga inviato a pi\u00f9 consumatori, detti subscriber, che si sono sottoscritti al topic. Questo modello consente una comunicazione decentrata, in cui gli eventi possono propagarsi simultaneamente a diversi sistemi, supportando scalabilit\u00e0 ed estensibilit\u00e0.<\/p>\n\n\n\n

<\/p>\n\n\n

\n
\"Point-to-Point
Canale di messaggistica Point-to-Point<\/em><\/figcaption><\/figure><\/div>\n\n\n

<\/p>\n\n\n

\n
\"Publish-Subscribe
Canale di messaggistica Publish-Subscribe<\/em><\/figcaption><\/figure><\/div>\n\n\n

<\/p>\n\n\n\n

Enterprise Integration Patterns<\/a> di Gregor Hohpe fornisce definizioni canoniche di entrambi i modelli, e queste idee sono fondamentali per le EDA moderne.<\/p>\n\n\n\n

Le dimensioni del coupling<\/h2>\n\n\n\n

Quando colleghiamo un Producer ad un Consumer tramite un canale di messaggistica, introduciamo un certo tipo di coupling. Una delle promesse principali delle EDA \u00e8 massimizzare la variabilit\u00e0 indipendente di Producer e Consumer. Ci\u00f2 significa che i componenti (in particolare i Consumer) dovrebbero poter cambiare senza impattare il resto del sistema.<\/p>\n\n\n\n

Ma il coupling non \u00e8 binario; esistono diverse dimensioni, ciascuna delle quali influisce su un aspetto diverso del comportamento del sistema. Esploriamo le cinque dimensioni principali del coupling \u2014 e come i diversi tipi di canali di messaggistica le supportano o le ostacolano.<\/p>\n\n\n\n

Temporal coupling<\/h4>\n\n\n\n

Cosa rappresenta:<\/strong> dipendenza temporale tra Producer e Consumer.<\/p>\n\n\n\n

Modifiche tipiche del Consumer:<\/strong> diventa temporaneamente non disponibile, rallenta a causa della latenza o del carico.<\/p>\n\n\n\n

Nei sistemi sincroni e fortemente accoppiati, un Producer deve attendere la risposta del Consumer. Ci\u00f2 crea fragilit\u00e0: se il Consumer non \u00e8 disponibile, il Producer rimane bloccato.<\/p>\n\n\n\n

Supporto dei canali di messaggi:<\/strong> sia i canali Point-to-Point (es. SQS) sia quelli Pub\/Sub (es. SNS) disaccoppiano i componenti attraverso la messaggistica asincrona.<\/p>\n\n\n\n

Il Producer emette un messaggio e prosegue. I consumatori prelevano o ricevono i messaggi quando sono pronti.<\/p>\n\n\n\n

Questo disaccoppiamento migliora la resilienza del sistema, poich\u00e9 i produttori non dipendono dalla disponibilit\u00e0 immediata dei consumatori.<\/p>\n\n\n\n

Location Coupling<\/h4>\n\n\n\n

Cosa rappresenta:<\/strong> dipendenza del Producer<\/em> dalla posizione fisica o logica del Consumer<\/em>.<\/p>\n\n\n\n

Modifiche tipiche del Consumer<\/em>:<\/strong> viene spostato su un altro host, in una availability zone diversa, in una nuova regione o viene scalato orizzontalmente su pi\u00f9 istanze.<\/p>\n\n\n\n

In scenari tradizionali come le chiamate RPC, il Producer<\/em> \u00e8 consapevole dell\u2019indirizzo del Consumer<\/em>, che si tratti di un hostname o di un endpoint. Questo implica che ogni cambiamento infrastrutturale \u2014 come la migrazione o la replica del Consumer<\/em> \u2014 pu\u00f2 richiedere modifiche al Producer<\/em>.<\/p>\n\n\n\n

Supporto dei canali di messaggi:<\/strong><\/p>\n\n\n\n

I canali di messaggistica (es. SQS, SNS, EventBridge) riducono questo tipo di accoppiamento, poich\u00e9 sono generalmente costrutti logici. Il Producer<\/em> invia messaggi a un canale, senza conoscere la posizione dei Consumer<\/em>. Questo permette ai Consumer<\/em> di spostarsi, duplicarsi o scalare senza impattare i Producer<\/em>.<\/p>\n\n\n\n

Tuttavia, quando un canale \u00e8 vincolato a una specifica availability zone o regione, il disaccoppiamento geografico pu\u00f2 essere parziale.<\/p>\n\n\n\n

Space coupling<\/h4>\n\n\n\n

Cosa rappresenta:<\/strong> una dipendenza strutturale che presuppone una comunicazione diretta tra Producer<\/em> e Consumer<\/em>, senza componenti intermedi.<\/p>\n\n\n\n

Modifiche tipiche del Consumer<\/em>:<\/strong> il Consumer viene spostato dietro un proxy, un API gateway, o un altro intermediario.<\/p>\n\n\n\n

Lo space coupling<\/em> si riferisce alla difficolt\u00e0 di introdurre un intermediario tra Producer<\/em> e Consumer<\/em> senza dover modificare la logica del mittente. In architetture fortemente accoppiate, il Producer<\/em> si aspetta di comunicare direttamente con il Consumer<\/em>, e qualsiasi cambiamento nella catena \u2014 come l\u2019inserimento di un layer di routing, filtraggio o trasformazione \u2014 richiede spesso aggiornamenti sul lato del Producer<\/em> stesso.<\/p>\n\n\n\n

Supporto dei canali di messaggi:<\/strong><\/p>\n\n\n\n

I canali di messaggistica \u2014 sia Point-to-Point<\/em> che Publish-Subscribe<\/em> \u2014 offrono un valido disaccoppiamento da questo punto di vista. Partendo da una situazione in cui il Producer<\/em> comunica con il Consumer tramite un canale di messaggistica, \u00e8 possibile introdurre broker, event bus<\/em>, o altri componenti intermedi senza alterare il comportamento del Producer<\/em>.<\/p>\n\n\n\n

Topology coupling<\/h4>\n\n\n\n

Cos’\u00e8:<\/strong> la possibilit\u00e0 di aggiungere nuovi Consumer (nuove logiche applicative) senza impattare il Producer o introdurre anti-pattern.<\/p>\n\n\n\n

Modifiche tipiche del Consumer:<\/strong> Una nuova applicazione Consumer ha bisogno di ricevere gli stessi eventi.<\/p>\n\n\n\n

Qui la distinzione tra tipi di canali diventa critica.<\/p>\n\n\n\n

Nei canali Point-to-Point come SQS, solo un Consumer pu\u00f2 ricevere con successo ogni messaggio. Aggiungere un secondo Consumer alla stessa coda \u00e8 un anti-pattern: si creano race condition, dove solo uno di n Consumer riceve il messaggio.<\/p>\n\n\n\n

Al contrario, i canali Publish-Subscribe come i topic SNS sono progettati per supportare pi\u00f9 consumatori. Ogni subscriber riceve una copia del messaggio.<\/p>\n\n\n\n

Implicazioni dei canali di messaggi:<\/strong><\/p>\n\n\n\n