Che cos'è il pattern pub/sub (publish-subscribe)?

Aggiornato: ottobre 2026

Il pub/sub è un pattern di messaggistica in cui i publisher inviano messaggi a dei topic su un broker e ogni subscriber di un topic ne riceve una copia. Tutto il suo valore sta in ciò che le parti non sanno: i publisher non scoprono mai chi ascolta, i subscriber non scoprono mai chi ha inviato – l’indirezione del broker li disaccoppia nello spazio (sistemi diversi), nel tempo (i subscriber possono essere offline) e nella sincronizzazione (la pubblicazione restituisce subito il controllo). Si aggiungono subscriber senza toccare i publisher: è il superpotere discreto del pattern.

Punti chiave

DomandaRisposta
Gli attoriPublisher → messaggio → topic → broker → subscriber (ognuno riceve una copia)
vs. una codaUna coda ripartisce il lavoro verso un solo consumatore; il pub/sub lo duplica verso tutti
vs. observerL’observer è interno al processo e sincrono; il pub/sub passa da un broker ed è asincrono
La posizione predefinitaConsegna at-least-once + handler idempotenti
Le clausole in piccoloNessuna risposta, nessun ordine predefinito, nessuna transazione atomica attraverso il broker

Il pattern in codice

Qualunque API pub/sub si riduce a due verbi, indipendentemente dal broker:

// Subscriber – dichiarano interesse per un topic
broker.subscribe('orders.paid', (msg) => fulfill(msg));   // servizio A
broker.subscribe('orders.paid', (msg) => notifyUser(msg)); // servizio B – copia propria

// Publisher – fire and forget
broker.publish('orders.paid', { orderId: 'o-1187' });
// Il publisher non scopre mai chi l'ha ricevuto – né se qualcuno l'ha ricevuto.

La stessa forma sul lato client, dove una sottoscrizione live query fa da topic e una scrittura sul database fa da pubblicazione:

// JavaScript / Node.js — Back4app JS SDK
// Pub/sub at the edge: live queries subscribe, saves publish
// Subscriber — register interest in a topic
const topic = new Parse.Query('Event');
topic.equalTo('topic', 'orders');
const sub = await topic.subscribe();
sub.on('create', (event) => handle(event.get('payload')));

// Publisher — fire and forget; no knowledge of subscribers
const event = new Parse.Object('Event');
event.set('topic', 'orders');
event.set('payload', { orderId: 'o-1187', status: 'paid' });
await event.save();

Come funziona il pub/sub

Flusso di messaggi publish-subscribe attraverso un brokerUn publisher invia un messaggio a un topic con un nome ospitato da un broker di messaggi. Il broker confronta il topic con le sottoscrizioni registrate e consegna una copia indipendente del messaggio a ogni subscriber, che ne conferma l'elaborazione separatamente.

publish(orders.paid, msg)

copia 1

copia 2

copia 3

Publisher
(fire & forget)

Broker
topic: orders.paid

Subscriber A
evasione ordini

Subscriber B
notifiche

Subscriber C
analytics

Un publisher invia un messaggio a un topic con un nome ospitato da un broker di messaggi. Il broker confronta il topic con le sottoscrizioni registrate e consegna una copia indipendente del messaggio a ogni subscriber, che ne conferma l'elaborazione separatamente.

Il broker svolge quattro compiti: accettare le pubblicazioni e restituire subito il controllo; far corrispondere ogni messaggio alle sottoscrizioni (per nome del topic, in modo gerarchico – orders.* – oppure per attributi di contenuto); consegnare una copia indipendente a ogni subscriber, con retry secondo il suo livello di garanzia; e conservare i messaggi per i subscriber offline dove la durabilità è configurata – il disaccoppiamento temporale che permette a un servizio rilasciato a mezzogiorno di recuperare ciò che ha perso. Una nota di vocabolario che merita una frase: il messaggio è la busta; l’evento – “questo è accaduto”, al passato – è ciò che il pub/sub trasporta di solito, e il fatto che porti il solo accaduto oppure lo stato completo è la distinzione di Fowler fra event notification ed event-carried state transfer.

Pub/sub vs. code di messaggi vs. pattern observer

Le due confusioni, risolte in una tabella:

CriterionPub/subCoda di messaggiObserver
ConsegnaOgni subscriber riceve una copiaUn solo worker consuma ciascun messaggioIl soggetto chiama ogni observer
RuoloDiffondere eventiRipartire il lavoroReagire a uno stato dentro il processo
AccoppiamentoNessuno – mediato dal brokerNessuno – mediato dalla codaRiferimenti diretti fra oggetti
TempiAsincronoAsincronoDi solito sincrono
ConfineFra processi e sistemiFra workerDentro un solo processo
Forma canonica1 evento → N reazioniN job → M worker1 oggetto → i suoi listener

La formula che sopravvive alla riunione: una coda ripartisce il lavoro; il pub/sub lo duplica. E l’observer non è un “pub/sub in piccolo” – l’indirezione del broker è esattamente ciò che all’observer manca, ed è per questo che trasformare un observer in pub/sub è un cambio di architettura, non una rinominazione. In pratica i broker offrono entrambe le forme: i consumer group trasformano un topic in una coda per gruppo (la mossa distintiva di Kafka), gli exchange fanout trasformano un sistema di code in pub/sub.

Garanzie di consegna: at-most-once vs. at-least-once vs. exactly-once

GaranziaModalità di guastoCostoL’handler deveSceglierla quando
At-most-onceI messaggi possono svanireIl più economico, il più rapidoTollerare i buchiDati effimeri: presenza, ticker, metriche
At-least-onceArrivano duplicatiAck + retryEssere idempotenteÈ la scelta predefinita per gli eventi di business
Exactly-onceVincolato, complessoDeduplicazione + coordinamentoRestare idempotentePercorsi ristretti in cui il broker lo consente

I livelli QoS 0/1/2 di MQTT corrispondono esattamente a questi tre – una conferma netta che la tricotomia è fondamentale e non un argomento di marketing. La verità di chi progetta: l’exactly-once da un capo all’altro è inarrivabile nel caso generale (il problema dei due generali con il distintivo del broker); i sistemi che lo annunciano combinano consegna at-least-once e deduplicazione. Per questo il vero contratto del pattern si scrive nel proprio handler: at-least-once + idempotenza – deduplicare su un ID del messaggio, usare upsert con chiave sull’entità oppure verificare la versione prima di applicare – trasforma i duplicati da bug in no-op.

Ordine, dead letter e progettazione dei topic

Tre realtà operative che i diagrammi introduttivi saltano. L’ordine: il fan-out verso consumatori paralleli non ha ordine globale; i broker lo ripristinano per partizione o per chiave di ordinamento, al prezzo del parallelismo – conviene progettare gli handler perché applichino gli eventi per ID dell’entità e per versione, non per ordine di arrivo, e il problema si dissolve in buona parte. I messaggi avvelenati: un messaggio la cui elaborazione solleva sempre un’eccezione viene ritentato all’infinito in at-least-once; conviene limitare i tentativi di consegna e instradare i fallimenti verso una dead letter queue per il triage, altrimenti un solo evento difettoso blocca il topic. La progettazione dei topic: nomi gerarchici (orders.paid, orders.refunded, jolly orders.*), granularità al livello su cui i subscriber differiscono davvero, ed evoluzione additiva degli schemi dei messaggi – i subscriber ignorano i campi sconosciuti; le modifiche incompatibili ricevono un nuovo topic versionato (orders.v2) con una finestra di migrazione, esattamente come una versione di API.

Casi d’uso tipici

  • Integrazione di microservizi – servizi di team diversi che reagiscono agli eventi degli altri senza chiamate dirette né calendari di deployment condivisi.
  • Funzionalità in tempo reale lato client – fan-out di chat, dashboard in diretta, presenza: pub/sub su WebSocket lato client.
  • Telemetria IoT – migliaia di dispositivi che pubblicano via MQTT; consumatori che vanno dagli avvisi all’analytics e si sottoscrivono in modo indipendente.
  • Invalidazione della cache e replica – una scrittura pubblicata, e ogni cache e ogni replica avvisate.
  • Pipeline di elaborazione in parallelo – un evento che avvia insieme evasione, notifica e analytics, ognuna con i propri tempi.

Conviene usare il pub/sub? Matrice decisionale

Il pub/sub va bene quando…Meglio qualcos’altro quando…
Un evento interessa più consumatori indipendentiC’è un solo consumatore: una coda, o una semplice chiamata
Produttori e consumatori rilasciano in modo indipendenteChi chiama ha bisogno della risposta subito → richiesta-risposta
L’eventual consistency (coerenza finale) è accettabileServe atomicità fra le parti → transazioni o saga
I subscriber vanno e vengono col tempoUn ordine globale stretto non è negoziabile
Un carico a picchi va ammortizzato fra sistemiTutto il sistema sta in un solo processo → observer

Limiti e trade-off

  • Il debug attraversa un broker. “Chi ha consumato questo, e perché è fallito?” esige ID di correlazione e tracing; il disaccoppiamento che libera i team nasconde anche la causalità.
  • Nessuna risposta, per progetto. I workflow che hanno bisogno di risposte devono modellarle come messaggi ulteriori – latenza in più e macchine a stati dove bastava una chiamata di funzione.
  • Il broker è infrastruttura. Disponibilità, capacità, sicurezza e politiche di conservazione del livello di messaggistica diventano lavoro di piattaforma; un broker fuori servizio moltiplica gli incidenti.
  • La cecità del publisher è un’arma a doppio taglio. I publisher non vedono la salute dei subscriber; un consumatore che fallisce in silenzio perde dati se non esiste un monitoring delle dead letter.
  • Le garanzie costano throughput. Le chiavi di ordinamento serializzano, l’exactly-once coordina, la durabilità persiste – ogni rafforzamento della semantica si paga in prestazioni; conviene comprare solo ciò di cui i dati hanno davvero bisogno.

Il pub/sub su Back4app

Back4app è una piattaforma open-source di Backend as a Service (BaaS) che combina database gestito, API REST e GraphQL generate automaticamente, autenticazione, archiviazione di file e funzioni serverless con Cloud Code. Il pattern compare qui sul lato client: le Live Queries sono pub/sub in cui la query è il topic – i subscriber registrano un predicato, e qualsiasi scrittura che corrisponda a quel predicato viene pubblicata verso ogni subscriber su una flotta gestita di WebSocket, con i permessi verificati per singolo subscriber e il fan-out gestito dalla piattaforma, come nelle schede di codice qui sopra. Le reazioni lato server si compongono allo stesso modo: i trigger Cloud Code si sottoscrivono alle modifiche dei dati (afterSave come sottoscrizione a un topic, nello spirito) e le funzioni pianificate smaltiscono il lavoro pubblicato sotto forma di righe. Per lo streaming intenso fra servizi la scelta resta un broker dedicato come Kafka o RabbitMQ – ma per i casi di prodotto più comuni la diffusione a ogni cambiamento arriva insieme al backend.

Domande frequenti

Che cos'è il pub/sub in parole semplici?

Un pattern di messaggistica in cui i mittenti (i publisher) pubblicano messaggi su topic con un nome ospitati da un broker, e ogni componente che si è sottoscritto a quel topic riceve la propria copia – publisher e subscriber non si conoscono mai. Vale l'immagine della radio: la stazione trasmette su una frequenza; chi si sintonizza, ascolta.

Qual è la differenza tra il pub/sub e una coda di messaggi?

Una coda ripartisce il lavoro; il pub/sub lo duplica. In una coda ogni messaggio viene consumato da un solo worker – lo strumento per distribuire job su un pool. Nel pub/sub ogni subscriber del topic riceve una copia – lo strumento per diffondere eventi verso parti interessate in modo indipendente l'una dall'altra.

Qual è la differenza tra il pub/sub e il pattern observer?

L'observer vive dentro un solo processo: il soggetto conserva riferimenti diretti ai propri observer e di solito li chiama in modo sincrono. Il pub/sub intercala un broker fra le parti, le disaccoppia completamente, rende lo scambio tipicamente asincrono e consente loro di vivere in processi, linguaggi e deployment diversi. Uno è un design pattern interno a un'app; l'altro è un'architettura fra sistemi.

Che cos'è un topic nel pub/sub?

Un canale logico con un nome che categorizza i messaggi: i publisher si rivolgono al topic e il broker consegna ogni messaggio a tutti i subscriber di quel topic. Il filtraggio può essere per topic (sottoscrizione per nome, spesso gerarchica – orders.*) oppure per contenuto, con il broker che confronta gli attributi dei messaggi.

Quali garanzie di consegna offre il pub/sub?

Tre livelli. At-most-once: fire-and-forget – rapido, qualche messaggio può perdersi. At-least-once: retry fino alla conferma – la scelta predefinita più comune, che produce duplicati occasionali. Exactly-once: deduplicazione più coordinamento – costoso, vincolato e impossibile da garantire da un capo all'altro nel caso generale. La posizione pragmatica: consegna at-least-once con handler idempotenti.

Il pub/sub garantisce l'ordine dei messaggi?

Non per impostazione predefinita – i messaggi partono in fan-out verso subscriber paralleli, e un ordine globale combatte il parallelismo. I broker sanno ordinare dentro una partizione o una chiave di ordinamento, al prezzo del throughput. Una progettazione robusta presuppone un ordine solo dove è configurato in modo esplicito e scrive handler che tollerano gli arrivi fuori sequenza.

Kafka è pub/sub?

Sì, con una sfumatura: Apache Kafka implementa la semantica publish-subscribe sopra un commit log partizionato, durevole e riproducibile (replay). Dentro un consumer group si comporta come una coda (ogni messaggio va a un solo membro); fra gruppi diversi si comporta come pub/sub (ogni gruppo riceve una copia) – ed è per questo che di solito si parla di event streaming.

Quando conviene evitare il pub/sub?

Quando chi chiama ha bisogno di una risposta immediata (richiesta-risposta), quando alcune operazioni devono essere atomiche fra produttore e consumatori (un broker non può partecipare a una transazione – si veda il pattern saga), quando serve un ordine globale stretto, oppure quando il sistema è abbastanza piccolo perché un broker aggiunga più superficie operativa di quanta ne tolga.

Termini correlati

Confronta con

Fonti di approfondimento

Pronto a costruire il tuo backend?

Avvia il tuo progetto su Back4app in pochi minuti: database, autenticazione, API e Cloud Code inclusi. Nessuna carta di credito richiesta.

Scritto e revisionato da Back4app Engineering, Back4app Engineering · Pubblicato il 2026-10-19