Perché Rabbit? Cos’è MQ? Come può migliorare le nostre applicazioni? Perché dovrei volerne sapere di più? – Queste sono le domande che mi sono posto quando sono stato presentato per la prima volta a RabbitMQ. Sono Gabor, e ora sono un ingegnere e consulente di RabbitMQ. Nel mio tempo di lavoro con RabbitMQ, ho imparato che anche i clienti esperti fanno queste domande.
TL;DR > Controlla la nostra pagina del prodotto RabbitMQ per i casi d’uso, le caratteristiche e per contattare i nostri consulenti esperti.
Quale problema risolve RabbitMQ?
Prima di addentrarci in cosa sia RabbitMQ e come usarlo, vale la pena imparare di più sul dominio del problema stesso. La comunicazione tra diversi servizi (a.k.a. computer) è un problema antico.
Da un lato, ci sono i diversi protocolli che definiscono i mezzi di trasporto e le proprietà della comunicazione. Alcuni esempi di tali protocolli includono SMTP, FTP, HTTP o WebSockets (per nominarne alcuni), che sono tutti basati su TCP/UDP. Si occupano della formattazione, dell’affidabilità e della ricerca del destinatario corretto di un messaggio.
D’altra parte, possiamo esplorare la comunicazione dalla prospettiva del messaggio. Esiste in un sistema, poi viene trasportato in un altro, viene trasformato, cioè ha un ciclo di vita. Mentre viaggia da un sistema all’altro, dovremmo essere consapevoli di dove si trova il messaggio, e chi ne è il proprietario in un dato momento.
I protocolli di comunicazione menzionati sopra possono assicurarsi che la proprietà (e la posizione “fisica”) del messaggio sia trasferita da un sistema all’altro (anche se può richiedere un po’ di tempo per eseguire questa transazione). Possiamo considerare il trasferimento come una transazione tra le due parti mentre entrambe sono presenti. Il più delle volte, questo scambio attivo è desiderabile, ad esempio chiedendo lo stato del servizio e aspettandosi una risposta tempestiva e accurata. Un esempio dal mondo fisico sarebbe chiamare qualcuno al telefono:
1) iniziamo la chiamata,
2) aspettiamo che l’altra parte risponda,
3) abbiamo una bella discussione,
4) riagganciamo il telefono.
Ma ci sono altre volte in cui non abbiamo bisogno della risposta, abbiamo solo bisogno che il ricevitore si appropri del messaggio e faccia il suo lavoro. In questo caso, abbiamo bisogno di un agente intermediario, un altro sistema che si appropri del messaggio (temporaneamente) e si assicuri che il messaggio raggiunga la sua destinazione. Per spingere ulteriormente l’esempio del telefono, l’altra parte non è disponibile al momento, quindi lasciamo un messaggio vocale. Il servizio di segreteria telefonica avviserà il destinatario.
Questa consegna asincrona (ritardata) del messaggio è ciò che RabbitMQ fornisce. Ovviamente, può fare più di una semplice segreteria telefonica, quindi esploriamo alcune delle opzioni che fornisce di seguito
(Se siete interessati a saperne di più sulla storia di RabbitMQ, vi consiglio il primo capitolo di “RabbitMQ in Action” di Alvaro Videla e Jason Williams. Rivelerà la risposta al perché si chiama come i conigli).
RabbitMQ è una soluzione di accodamento dei messaggi gratuita, open-source ed estensibile. È un message broker che capisce AMQP (Advanced Message Queuing Protocol), ma è anche in grado di essere utilizzato con altre soluzioni di messaggistica popolari come MQTT. È altamente disponibile, tollerante agli errori e scalabile. È implementato in Erlang OTP, una tecnologia fatta su misura per costruire sistemi stabili, affidabili, tolleranti ai guasti e altamente scalabili che possiedono capacità native di gestire un gran numero di operazioni simultanee, come nel caso di RabbitMQ e altri sistemi come WhatsApp, MongooseIM, per citarne alcuni.
A un livello molto alto, è uno strato middleware che consente a diversi servizi nella vostra applicazione di comunicare tra loro senza preoccuparsi della perdita di messaggi, fornendo diversi requisiti di qualità del servizio (QoS). Permette anche un instradamento dei messaggi efficiente e a grana fine, consentendo un ampio disaccoppiamento delle applicazioni.
Casi d’uso
Per mostrare la versatilità di RabbitMQ, useremo tre casi di studio che dimostrano come RabbitMQ sia adatto come un approccio di servizio gestito a scatola nera, come uno che si integra strettamente con l’applicazione consentendo un’architettura a microservizi ben funzionante, o come un gateway per altri progetti legacy.
RabbitMQ come message-bus generale
Quando un sistema monolitico viene suddiviso in sottosistemi separati, uno dei più grandi problemi da risolvere è quale tecnologia di comunicazione utilizzare. Una soluzione come Mulesoft, o MassTransit può “cablare” i servizi dichiarando ascoltatori e mittenti HTTP. Questo tipo di soluzione tratta RabbitMQ come una scatola nera, ma è ancora in grado di sfruttare le capacità di RabbitMQ. Come esempio di comunicazione diretta, usiamo HTTP per “collegare” i singoli servizi. Anche se è una scelta ben supportata e solida, ha alcuni svantaggi:
1) La scoperta dei servizi non è risolta. Una possibile soluzione è usare il DNS. Come il sistema scala e cresce, così anche la complessità di trovare e bilanciare questo carico. RabbitMQ può mitigare la maggiore complessità della soluzione.
2) La comunicazione è effimera. I messaggi sono inclini ad essere abbandonati o duplicati sul livello di rete. Se un servizio non è temporaneamente disponibile, la consegna fallisce.
RabbitMQ può aiutare in entrambi i casi utilizzando le code di messaggi come mezzo di trasporto. I servizi possono pubblicare e consumare messaggi, il che disaccoppia la consegna del messaggio end-to-end dalla disponibilità del servizio di destinazione. Se un servizio che consuma è temporaneamente non disponibile, a differenza di HTTP, il messaggio viene bufferizzato in modo sicuro e conservato in RabbitMQ, ed eventualmente consegnato quando il servizio torna online.
Anche la reperibilità è semplificata. Tutto quello che dobbiamo sapere è dove si trova RabbitMQ e qual è il nome della coda. Anche se sembra che questo reinventi il problema, questo è scalabile. Il nome della coda funge da indirizzo del servizio. Il consumo di messaggi dalle code da parte dei singoli servizi offre un mezzo per la scalabilità, cioè ogni coda può servire più consumatori e bilanciare il carico. Non c’è bisogno di cambiare la configurazione delle code già incorporata nei servizi.
Questa configurazione moderatamente statica delle code spinge RabbitMQ a un livello middleware dove un solido design può garantire una qualità di servizio stabile a lungo termine.
RabbitMQ come livello di routing avanzato per micro-servizi
Sull’altra estremità dello spettro c’è un’architettura che è più fluida e si adatta alle esigenze sempre mutevoli di molti micro-servizi. Ciò che fa brillare RabbitMQ in questo ambiente sono le capacità di routing molto potenti che fornisce.
La logica di routing è implementata in diversi (cosiddetti) tipi di scambio che possono essere creati dinamicamente dall’applicazione quando necessario. I servizi di destinazione creano le code da cui desiderano consumare, poi le legano agli scambi specificando un modello per le chiavi che gli editori possono usare quando pubblicano il messaggio. (Pensa a queste chiavi come metadati che gli scambi possono usare per instradare e consegnare i messaggi a una o più code.)
La logica di instradamento è implementata in diversi (cosiddetti) tipi di scambio che possono essere creati dinamicamente dall’applicazione quando necessario. I servizi di destinazione creano le code da cui desiderano consumare, poi le legano agli scambi specificando un modello per le chiavi che gli editori possono usare quando pubblicano il messaggio. (Pensa a queste chiavi come metadati che gli scambi possono usare per instradare e consegnare i messaggi a una o più code.)
RabbitMQ è dotato di quattro utili tipi di scambio che coprono la maggior parte dei casi d’uso della messaggistica:
1) Scambio diretto. Questo consegnerà il messaggio in arrivo a qualsiasi coda la cui chiave di binding corrisponde esattamente alla chiave di routing del messaggio. Se si legano le code con il nome della coda come chiavi di instradamento, allora si può pensare ad una consegna del messaggio uno a uno. È semplice consegnare lo stesso messaggio a più code usando le chiavi di binding per più code.
2) Scambio di argomenti. Questo consegnerà il messaggio in arrivo a qualsiasi coda la cui chiave di binding jolly corrisponde alla chiave di instradamento del messaggio pubblicato. Le chiavi di collegamento possono contenere criteri di corrispondenza jolly per una chiave di instradamento composta. (ad esempio, la chiave di binding logs.*.error
corrisponderà alle chiavi di routing logs.accounting.error
e logs.ui.error
). Questo ci permette di scrivere servizi semplici dove la logica è ben contenuta, e il messaggio arriverà ai servizi corretti attraverso la “magia” di RabbitMQ.
3) Scambio fanout. Alcuni messaggi hanno bisogno di essere consegnati a tutte le code, questo è il caso in cui uno scambio fanout può essere usato invece di scrivere un’elaborata logica multicast nell’applicazione. Con uno scambio fanout di RabbitMQ, ogni servizio lega la coda appropriata allo scambio senza bisogno di specificare una chiave di binding, e tutto avviene automaticamente. Se viene specificata una chiave di binding, lo scambio fanout semplicemente la ignorerà e continuerà a instradare/trasmettere messaggi a tutte le code ad essa collegate.
4) Scambio di intestazioni. Questo scambio sfrutta la struttura dei messaggi AMQP ed è in grado di effettuare un routing complesso basato sulle intestazioni (comprese quelle personalizzate) del messaggio AMQP. Le intestazioni sono metadati allegati ad ogni messaggio inviato via AMQP.
Oltre agli scambi, ci sono altre utili caratteristiche in RabbitMQ che permettono l’implementazione di una logica di messaggistica molto complessa. Alcune delle caratteristiche più importanti includono:
1) Plug-in personalizzati. RabbitMQ è estensibile permettendo ai suoi utenti di aggiungere plug-in. Quasi ogni aspetto di RabbitMQ è personalizzabile, compresa la gestione, l’autenticazione e l’autorizzazione, le soluzioni di back-up e il clustering.
2) Clustering. Quando un singolo server RabbitMQ non è sufficiente, più broker RabbitMQ possono essere collegati per lavorare insieme e scalare il sistema. Può permettere a RabbitMQ di elaborare più messaggi o aumentare la resilienza agli errori.
3) Messa a punto della qualità del servizio. La consegna dei messaggi sensibili al tempo può essere aiutata attaccando un valore TTL (Time-to-Live) al messaggio o alla coda. I messaggi scaduti possono essere consegnati automaticamente a una coda di messaggi morti. Combinando la logica di routing ordinaria e queste caratteristiche extra si possono ottenere logiche di routing molto avanzate. Un’altra utile caratteristica è l’uso di code di priorità dove l’editore può assegnare un livello di priorità ad ogni messaggio. È anche possibile limitare il numero di messaggi non riconosciuti, il che permette la regolazione delle prestazioni dei servizi che consumano, in questo caso, RabbitMQ applica un meccanismo di back-pressure.
RabbitMQ integrato in sistemi legacy
Nel caso d’uso precedente, ho menzionato la possibilità di usare plug-in per estendere le funzionalità di RabbitMQ. Questa potente caratteristica permette a RabbitMQ di agire come un livello di mediazione tra i servizi nativi di RabbitMQ (capaci di AMQP) e altre applicazioni legacy. Alcuni esempi notevoli includono:
1) Usare RabbitMQ come un broker MQTT semplicemente abilitando un plug-in. Questo apre il panorama a molte tecnologie IoT.
2) Il plug-in JMS (Java Message Service) di RabbitMQ, che permette a RabbitMQ di comunicare con qualsiasi soluzione di messaggistica capace di JMS.
3) Se la vostra applicazione utilizza un protocollo proprietario per comunicare, è possibile sviluppare un plugin personalizzato per connettersi a qualsiasi servizio di questo tipo.
Conclusione
Come dimostrano gli esempi precedenti, non c’è quasi nulla con cui RabbitMQ non possa comunicare. Ma come ogni cosa nella vita, ha un prezzo. Anche se la configurazione di RabbitMQ è per lo più semplice, a volte il solo numero di caratteristiche può essere schiacciante. Se avete problemi con la progettazione, l’implementazione o il supporto dei vostri broker RabbitMQ, contattate il nostro team di esperti qui. Oppure, se vuoi iniziare la tua carriera in una delle tecnologie più richieste, iscriviti al nostro corso di formazione di 3 giorni su RabbitMQ.
Debugging RabbitMQ
Vuoi un sistema intuitivo che renda facile il monitoraggio e la manutenzione del tuo RabbitMQ? Ottieni subito la tua prova gratuita di 45 giorni di WombatOAM.
La nostra pagina delle capacità di RabbitMQ