Non c’è ombra di dubbio che parlando di protocolli per lo scambio di messaggi fra applicazioni ci si imabatta a confrontarsi con questi due signori. Allora, perchè non cercare di capire che differenze ci sono fra due protocolli apparentemente molto simili?
MQTT è stato progettato per l’Internet of Things (IoT), argomento a me molto caro. Dispone di un solo meccanismo di instradamento, ossia le sottoscrizioni ai topics.
AMQP è stato creato per fornire un protocollo di messaggistica ad alte prestazioni. Dispone di molte funzioni per soddisfare una serie di scenari di messaggistica, perciò è anche più complesso di MQTT. Le sue destinazioni principali sono i messaggi per le code, ma dispone anche di altri metodi di instradamento.
Entrambi vengono eseguiti su connessioni TCP, dispongono di architettura client-server e sono bidirezionali.
Alla scoperta di MQTT
Abbiamo detto che si tratta di un protocollo con caratteristiche specifiche per le soluzioni IoT
- Utilizza connessioni TCP per l’affidabilità, la frammentazione e l’ordinamento. Garantisce la consegna dei pacchetti e permette il controllo di eventuali errori.
- Cerca di ridurre al minimo l’overhead dei dati di ciascun pacchetto MQTT
- E’ posssibile memorizzare “the last known good data value“, ossia l’ultimo valore noto dei dati di un dispositivo
- E’ in grado di notificare quando un dispositivo si disconnette inaspettatamente (will message), permettendo il monitoraggio dello stato del Client
- Dispone di un flusso di comunicazione bidirezionale, ossia i dati ed i comandi ai dispositivi possono sfruttare la stessa connessione TCP
- Favorisce l’aggiunta di altri consumer grazie al publish subscribe.
MQTT mette a disposizione alcuni comandi: CONNECT, SUBSCRIBE, PUBLISH, UNSUBSCRIBE e DISCONNECT.
Ma dispone anche di topics. I topics sono l’unità di distribuzione dei dati a cui i client possono sottoscriversi per pubblicare (PUBLISH) o ricevere (SUBSCRIBE) le informaizoni desiderate. Ogni sottoscrittore ad un topic riceverà tutti i messaggi pubblicati sullo stesso. Non esiste un formato predefinito di topic, ogni applicazione, semplicemente, definisce il proprio.
Allo scoperta di AMPQ
AMQP è un protocollo di messaggistica creato per essere un metodo non proprietario di connessione delle applicazioni. Inizialmente, nella versione AMQP 0.9.1, è stato prodotto dal gruppo di lavoro AMQP, con la versione AMQP 1.0 è diventato uno standard OASIS, così come MQTT 3.1.1 e MQTT 5.0.
Questo passaggi di consegne ha un pò complicato il supporto di AMQP in termini di compatibilità.
AMQP, a differenza di MQTT, supporta diverse tipologie di routing, principalmente definite dall’applicazione stessa, offrendo una certa flessibilità, ovviamente a scapito della configurazione dell’applicazione stessa. Di seguito un esempio di routing che evidenzia i componenti fondamentali del protocollo
L’applicazione deve creare una coda (queue) se non esiste già, e poi deve legare questa coda ad un exchange. L’exchange è il perno dell’operazione di pubblicazione dei messaggi, che poi instrada alle code. Esistono quattro tipi di exchange predefiniti:
- Direct la routing key, ossia la chiave per instradare messaggi, corrisponde al nome della coda stesso
- Fanout tutte le code legate a questo exchange ricevono tutti i messaggi
- Topic l’instradamento avviene seguendo il pattern utilizzato durante il binding fra coda ed exchange
- Headers simile al precedente, ma utilizza gli headers dei messaggi per lìinstradamento
AMQP dispone di features che non sono disponibili in MQTT, se non dalla versione 5.0
- Message headers (solo MQTT 5.0)
- Connessioni leggere multiple su una connessione TCP (canali)
- Virtual hosts (ambienti server isolati)
Che il confronto abbia inizio
AMQP | MQTT | |
Full name | Protocollo avanzato di accodamento messaggi | Il gruppo OASIS è intervenuto rendendo la gestione del protocollo un pò problematica |
Architecture | Code, multicast (fanout), pub/sub, req/rep | Pub/Sub. Non c’è possibilità di avere a disposizione una comunicazione Request/Reply |
Command targets | Exchanges, Queues | Topics |
Underlying protocol | TCP/IP | TCP/IP |
Secure connections | TLS + username/password (è possibile il supporto a SASL) | TLS + username/password (è possibile il supporto a SASL) |
Client observability | Non conosce lo stato del Client | Will messages. Conosce lo stato del Client |
Messagging mode | Sincrono e asincrono | Asincrono, event-based |
Messagging queuing | Configurazione flessibile | Il broker mantiene i messaggi in coda per i sottoscrittori disconnessi |
Message overhead | 8 bytes (frame format) | 2 bytes |
Message size | 2GB teorici. 128MB massimo raccomandati | 256MB massimo |
Content type | Any (binary) | Any (binary) |
Topic matching | Level separator: / Wildcards: + # | Level separator: / Wildcards: + # |
Reliability | Two qualities of service: -without acks (=0) – with acks (=1) | Three qualities of service: 0 – fire and forget 1 – at least once 2 – once and only once |
Connection “multiplexing” | Si (channels) | No |
Message attributes | Si | Solo MQTT 5.0 |
Object persistence | Si | Si |
Quando e perchè utilizzare MQTT
Se state lavorando su applicazioni IoT ci sono due caratteristiche di MQTT che non trovano corrispondenza in AMQP e sono fondamentali per la buona riuscita del vostro progetto: will e retained messages. In termini di consumo (bytes on wire) MQTT vince a mani basse la sfida co AMQP, proprio perchè focalizzato su applicazioni IoT, caratteristica che lo rendono particolarmente efficace in presenza di dispositivi a bassa, o bassisima, potenza o di reti inaffidabili.
MQTT è più facile da configurare, la semplicità e la flessibilità sono proprio gli attibuti con cui si possono creare velocemente applicazioni. Il paradigma di scambio messaggi pub/sub consente una comunicazione event-based tra tutti i componenti dell’applicazione stessa.
Quando e perchè utilizzare AMQP
AMQP offre maggiorni capacità rispetto a MQTT per la gestione dei messaggi, infatti è stato progettato per scopi più generici, e non specifici come MQTT appunto. Il fatto che la configurazione del routing dei messaggi sia soggetta ad errori, per esempio, è assolutamente ingiustificabile e tollerabile in ambito IoT.
Il fatto che AMQP 0.9 e AMQP 1.0 siano completamente diversi comporta una certa complessità. Consiglierei di adottare la AMQP 1.0, unica standardizzata OASIS.
And the Winner is?
Come al solito, dipende! Ognuno dei due è stato progetto per scopi diversi, ed ognuno vince nel proprio ambito.
Se avete bisogno di utilizzare un’implementazione in .NET del protocollo AMQP potete valutare l’utilizzo della libreria Muflone.Transport.RabbitMQ che mantengo insieme all’amico Alessandro Colla.