Event Driven — Cheat Sheet

Tag: event-driven, architecture, pub-sub, message-broker, async, decoupling

Livello: intermedio

TL;DR: Architettura software in cui il flusso del programma è determinato da eventi generati, rilevati e consumati in modo asincrono, garantendo elevato disaccoppiamento e scalabilità.

Concetti chiave

Producer o Publisher genera ed emette eventi senza avere conoscenza di chi li riceverà.

Consumer o Subscriber si iscrive per ascoltare specifici eventi ed eseguire logica di business in risposta.

Message Broker o Event Bus è l'infrastruttura middleware (es. Kafka, RabbitMQ, EventBridge) che instrada gli eventi.

Disaccoppiamento forte: i servizi non comunicano direttamente tra loro, facilitando manutenzione e deploy indipendenti.

Elaborazione asincrona: i producer non restano in attesa (non bloccanti) della risposta dei consumer.

Eventual Consistency: la coerenza dei dati tra microservizi non è immediata ma viene raggiunta nel tempo.

Event Sourcing: lo stato di un'entità non è salvato come record singolo, ma calcolato riproducendo una sequenza immutabile di eventi passati.

Choreography vs Orchestration: in architetture a microservizi, l'event-driven favorisce la coreografia (ogni servizio agisce autonomamente all'evento) rispetto a un orchestratore centrale.

Domande tipiche e risposte pronte

Q: Qual è la differenza principale tra un'architettura Request-Response e una Event-Driven?R: Nella Request-Response i servizi sono accoppiati temporalmente e funzionalmente, se il destinatario è down la chiamata fallisce. Nell'Event-Driven il producer emette l'evento e prosegue; il consumer lo processerà non appena disponibile.

Q: Come gestisci il caso in cui un consumer non riesca a elaborare un evento per un errore temporaneo o permanente?R: Configuro policy di retry con backoff esponenziale. Se l'errore persiste dopo i tentativi massimi, indirizzo l'evento verso una Dead Letter Queue (DLQ) per analisi manuale o replay successivo.

Q: Come affronti il problema della ricezione duplicata degli eventi?R: Implemento i consumer in modo che siano idempotenti, utilizzando chiavi univoche (come un correlation ID) per scartare i messaggi già elaborati correttamente o effettuando upsert sul database.

Insidie e errori comuni

Mancanza di tracciabilità distribuita, rendendo complesso il debug (fondamentale usare un correlation ID propagato tra i servizi).

Assumere che l'ordine di arrivo degli eventi sia sempre garantito (dipende dal broker e dalle partizioni usate).

Progettare eventi troppo granulari o troppo pesanti, intasando la rete o violando la privacy dei dati nel payload.

Rischio di "Event Storming", dove un evento scatena una reazione a catena incontrollabile tra i vari servizi (loop infiniti).

Snippet e comandiTypeScript

```import { EventEmitter } from 'events';

class OrderService extends EventEmitter {

createOrder(orderData: any) {

// Logica di creazione ordine...

const order = { id: 123, status: 'CREATED', ...orderData };

// Emette l'evento per gli altri sottosistemi

this.emit('OrderCreated', order);

return order;

}

}

const orderService = new OrderService();

// Un ipotetico Consumer per le notifiche

orderService.on('OrderCreated', (order) => {

console.log([Notification Service] Invio email per ordine: ${order.id});

});

orderService.createOrder({ amount: 150 });

```

Da ripassare

[ ] Pattern CQRS in combinazione con Event Sourcing.

[ ] Implementazione e gestione del pattern Saga (Coreografia) tramite eventi.

[ ] Differenze architetturali tra Kafka (Log-based) e RabbitMQ (Queue-based).

Jarvis Interviews
Jarvis