En introduktion til RabbitMQ – Hvad er RabbitMQ?

Hvorfor Rabbit? Hvad er MQ? Hvordan kan det forbedre vores applikationer? Hvorfor vil jeg gerne lære mere om det? – Det er spørgsmål, som jeg stillede mig selv, da jeg først blev introduceret til RabbitMQ. Jeg hedder Gabor, og jeg er nu RabbitMQ-ingeniør og konsulent. I min tid med RabbitMQ har jeg lært, at selv erfarne kunder stiller disse spørgsmål.

TL;DR > Tjek vores RabbitMQ-produktside for at se anvendelsestilfælde, funktioner og for at kontakte vores ekspertkonsulenter.

Hvilket problem løser RabbitMQ?

Hvor vi går i dybden med, hvad RabbitMQ er, og hvordan man bruger det, er det værd at lære mere om selve problemdomænet. Kommunikation mellem forskellige tjenester (a.k.a. computere) er et ældgammelt problem.

På den ene side er der de forskellige protokoller, der definerer transportmidlerne og egenskaberne ved kommunikationen. Nogle eksempler på sådanne protokoller omfatter SMTP, FTP, HTTP eller WebSockets (for at nævne nogle få), som alle er baseret på TCP/UDP. De beskæftiger sig med formatering, pålidelighed og med at finde den korrekte modtager af en meddelelse.

På den anden side kan vi undersøge kommunikationen ud fra meddelelsens perspektiv. Den eksisterer i ét system, derefter transporteres den til et andet, bliver transformeret, det vil sige, den har en livscyklus. Når den bevæger sig fra det ene system til det andet, bør vi være opmærksomme på, hvor meddelelsen befinder sig, og hvem der ejer den på et givet tidspunkt.

De ovennævnte kommunikationsprotokoller kan sikre, at ejerskabet (og den “fysiske” placering) af meddelelsen overføres fra det ene system til det andet (selv om det kan tage noget tid at udføre denne transaktion). Vi kan betragte overførslen som en transaktion mellem de to parter, mens begge er til stede. Det meste af tiden er denne aktive udveksling ønskelig, f.eks. hvis man spørger om tjenestens status og forventer et rettidigt og præcist svar. Et eksempel fra den fysiske verden kunne være at ringe til nogen over telefonen:
1) vi starter opkaldet,
2) venter på, at den anden part svarer,
3) har en hyggelig samtale,
4) lægger røret på.

Men der er andre gange, hvor vi ikke har brug for svaret, vi har bare brug for, at modtageren tager ejerskab over meddelelsen og gør sit arbejde. I dette tilfælde har vi brug for en mellemmand, et andet system til at overtage ejerskabet af meddelelsen (midlertidigt) og sørge for, at meddelelsen når frem til sin destination. For at skubbe telefoneksemplet videre, er den anden part ikke tilgængelig i øjeblikket, så vi efterlader en talebesked. Voicemailtjenesten vil underrette den tiltænkte modtager.

Denne asynkrone (forsinkede) levering af meddelelser er det, som RabbitMQ tilbyder. Den kan naturligvis mere end en simpel telefonsvarer, så lad os undersøge nogle af de muligheder, den giver nedenfor

(Hvis du er interesseret i at lære mere om RabbitMQ’s historie, anbefaler jeg det første kapitel i “RabbitMQ in Action” af Alvaro Videla og Jason Williams. Det vil afsløre svaret på, hvorfor det er opkaldt efter kaniner).

RabbitMQ er en gratis, open source og udvidelig message queuing-løsning. Det er en message broker, der forstår AMQP (Advanced Message Queuing Protocol), men som også kan bruges med andre populære messaging-løsninger som MQTT. Den er meget tilgængelig, fejltolerant og skalerbar. Den er implementeret i Erlang OTP, en teknologi, der er skræddersyet til opbygning af stabile, pålidelige, fejltolerante og meget skalerbare systemer, som har native kapacitet til at håndtere et meget stort antal samtidige operationer, som det er tilfældet med RabbitMQ og andre systemer som WhatsApp, MongooseIM, for at nævne nogle få.

På et meget højt niveau er det et middlewarelag, der gør det muligt for forskellige tjenester i din applikation at kommunikere med hinanden uden at bekymre sig om tab af meddelelser, samtidig med at der stilles forskellige krav til tjenestekvaliteten (QoS). Det muliggør også finkornet og effektiv beskedrouting, der muliggør omfattende afkobling af applikationer.

Anvendelsestilfælde

For at vise RabbitMQ’s alsidighed vil vi bruge tre casestudier, der viser, hvordan RabbitMQ er velegnet som en black-box managed service-tilgang, som en, der integreres tæt med applikationen, hvilket muliggør en velfungerende mikroservice-arkitektur, eller som en gateway til andre legacy-projekter.

RabbitMQ som en generel message-bus

Når et monolit-system nedbrydes til separate delsystemer, er et af de største problemer, der skal løses, hvilken kommunikationsteknologi der skal anvendes. En løsning som Mulesoft eller MassTransit kan “kabellægge” tjenester ved at deklarere HTTP-lyttere og -afsendere. Denne type løsning behandler RabbitMQ som en sort boks, men er stadig i stand til at udnytte RabbitMQ’s muligheder. Som et eksempel på direkte kommunikation kan vi bruge HTTP til at “forbinde” de enkelte tjenester. Selv om det er et velunderstøttet og solidt valg, har det nogle ulemper:
1) Opdagelsen af tjenester er ikke løst. En mulig løsning er at bruge DNS. Efterhånden som systemet skaleres og vokser, bliver det også mere kompliceret at finde og balancere denne belastning. RabbitMQ kan afhjælpe den øgede kompleksitet i løsningen.
2) Kommunikationen er flygtig. Meddelelser er tilbøjelige til at blive droppet eller duplikeret på netværkslaget. Hvis en tjeneste er midlertidigt utilgængelig, mislykkes leveringen.

RabbitMQ kan hjælpe i begge tilfælde ved at udnytte meddelelseskøer som transportmiddel. Tjenester kan offentliggøre og forbruge meddelelser, hvilket afkobler end-to-end-meddelelsesleveringen fra tilgængeligheden af destinationstjenesten. Hvis en forbrugende tjeneste er midlertidigt utilgængelig, bliver meddelelsen i modsætning til HTTP sikkert bufferiseret og opbevaret i RabbitMQ og leveres til sidst, når tjenesten kommer online igen.

Det er også lettere at finde frem til den. Det eneste, vi behøver at vide, er, hvor RabbitMQ er, og hvad køens navn er. Selv om det virker som om dette bare genopfinder problemet, er dette skalerbart. Kønavnet fungerer som adressen på tjenesten. De enkelte tjenesters forbrug af meddelelser fra køerne giver mulighed for skalerbarhed, dvs. at hver kø kan betjene flere forbrugere og balancere belastningen. Der er ikke behov for at ændre den køkonfiguration, der allerede er indbygget i tjenesterne.

Denne moderat statiske køkonfiguration skubber RabbitMQ til et middlewarelag, hvor et solidt design kan garantere en stabil servicekvalitet på lang sigt.

RabbitMQ som et avanceret routinglag for mikro-tjenester

I den anden ende af spektret findes en arkitektur, der er mere flydende og tilpasser sig de stadigt skiftende behov i mange mikro-tjenester. Det, der får RabbitMQ til at skinne i dette miljø, er de meget kraftfulde routing-funktioner, det giver.

Routinglogikken er implementeret i forskellige (såkaldte) udvekslingstyper, der kan oprettes dynamisk af applikationen, når der er behov for det. Destinationstjenesterne opretter de køer, som de ønsker at forbruge fra, og binder dem derefter til udvekslinger ved at angive et mønster for de nøgler, som udgiverne kan bruge, når de offentliggør meddelelsen. (Tænk på disse nøgler som metadata, som udvekslingerne kan bruge til at dirigere og levere meddelelserne til en eller flere køer.)

Routinglogikken er implementeret i forskellige (såkaldte) udvekslingstyper, der kan oprettes dynamisk af programmet efter behov. Destinationstjenesterne opretter de køer, som de ønsker at forbruge fra, og binder dem derefter til udvekslinger ved at specificere et mønster for de nøgler, som udgiverne kan bruge, når de offentliggør meddelelsen. (Tænk på disse nøgler som metadata, som udvekslingerne kan bruge til at videresende og levere meddelelserne til en eller flere køer.)

RabbitMQ leveres med fire nyttige udvekslingstyper, der dækker de fleste af anvendelsestilfælde for messaging:
1) Direkte udveksling. Dette vil levere den indkommende meddelelse til enhver kø, hvis bindingsnøgle passer nøjagtigt til meddelelsens routingnøgle. Hvis du binder køerne med kønavnet som routingnøgler, kan du tænke på det som en en-til-en-meddelelseslevering. Det er enkelt at levere den samme meddelelse til flere køer ved at bruge bindingsnøgler for flere køer.
2) Emneudveksling. Dette vil levere den indkommende meddelelse til enhver kø, hvis wild-card-bindingsnøgle passer til den offentliggjorte meddelelses routingnøgle. Bindingsnøgler kan indeholde wild-card-matchingkriterier for en sammensat routingnøgle. (f.eks. vil bindingsnøglen logs.*.error matche routingnøglerne logs.accounting.error og logs.ui.error). Dette giver os mulighed for at skrive enkle tjenester, hvor logikken er godt indeholdt, og meddelelsen vil ankomme til de korrekte tjenester gennem RabbitMQ’s “magi”.
3) Fanout-udveksling. Nogle meddelelser skal leveres til alle køer, det er her en fanout exchange kan bruges i stedet for at skrive en udførlig multicast-logik i applikationen. Med en RabbitMQ fanout exchange binder hver tjeneste den relevante kø til udvekslingen uden at skulle angive en bindingsnøgle, og det hele sker automatisk. Hvis der er angivet en bindingsnøgle, vil fanout-udvekslingen simpelthen ignorere den og stadig videresende/broadcast-meddelelser til alle køer, der er bundet til den.
4) Headers-udveksling. Denne udveksling udnytter AMQP-meddelelsernes struktur og er i stand til kompleks routing baseret på AMQP-meddelelsens headere (herunder brugerdefinerede headere). Headers er metadata, der er knyttet til hver meddelelse, der sendes via AMQP.

Ud over udvekslinger er der andre nyttige funktioner i RabbitMQ, som gør det muligt at implementere meget kompleks messaging-logik. Nogle af de vigtigste funktioner omfatter:
1) Brugerdefinerede plug-ins. RabbitMQ kan udvides ved at give sine brugere mulighed for at tilføje plug-ins. Næsten alle aspekter af RabbitMQ kan tilpasses, herunder administration, autentificering og autorisation, backup-løsninger og clustering.
2) Clustering. Når en enkelt RabbitMQ-server ikke er nok, kan flere RabbitMQ-mæglere tilsluttes for at arbejde sammen og skalere systemet. Det kan gøre RabbitMQ i stand til at behandle flere meddelelser eller øge modstandsdygtigheden over for fejl.
3) Afstemning af servicekvalitet. Tidsfølsom levering af meddelelser kan hjælpes ved at tilknytte en TTL-værdi (Time-to-Live) til enten meddelelsen eller køen. Beskeder, hvis tid er udløbet, kan automatisk leveres til en Dead-letter-kø. Ved at kombinere almindelig routing-logik og disse ekstra funktioner kan man opnå meget avancerede routing-logikker. En anden nyttig funktion er anvendelse af prioriterede køer, hvor udgiveren kan tildele et prioriteringsniveau til hver enkelt meddelelse. Det er også muligt at begrænse antallet af ubekræftede meddelelser, hvilket giver mulighed for at indstille de forbrugende tjenesters ydeevne, i dette tilfælde anvender RabbitMQ en back-pressure-mekanisme.

RabbitMQ integreret i legacy-systemer

I den foregående use-case nævnte jeg muligheden for at bruge plug-ins til at udvide RabbitMQ’s funktionalitet. Denne kraftfulde funktion gør det muligt for RabbitMQ at fungere som et mæglingslag mellem dine RabbitMQ-native (AMQP-kompatible) tjenester og andre legacy-programmer. Nogle bemærkelsesværdige eksempler omfatter:
1) Brug af RabbitMQ som en MQTT-mægler ved blot at aktivere et plug-in. Dette åbner landskabet for mange IoT-teknologier.
2) RabbitMQ’s JMS-plugin (Java Message Service), som gør det muligt for RabbitMQ at kommunikere med enhver JMS-kompatibel messaging-løsning.
3) Hvis din applikation bruger en proprietær protokol til kommunikation, er det muligt at udvikle et brugerdefineret plugin til at oprette forbindelse til sådanne tjenester.

Konklusion

Som ovenstående eksempler viser, er der næsten ikke noget, som RabbitMQ ikke kan kommunikere med. Men som med alt andet i livet har det en pris. Selv om konfigurationen af RabbitMQ for det meste er ukompliceret, kan det blotte antal funktioner nogle gange være overvældende. Hvis du støder på problemer med at designe, implementere eller understøtte dine RabbitMQ-mæglere, kan du kontakte vores eksperthold her. Eller hvis du gerne vil kickstarte din karriere inden for en af de mest efterspurgte teknologier, så tilmeld dig vores 3-dages RabbitMQ-uddannelseskursus.

Debugging RabbitMQ

Vil du have et intuitivt system, der gør overvågning og vedligeholdelse af din RabbitMQ let? Få din gratis 45-dages prøveversion af WombatOAM nu.

Vores side om RabbitMQ-funktioner