En introduktion till RabbitMQ – Vad är RabbitMQ?

Varför Rabbit? Vad är MQ? Hur kan det förbättra våra tillämpningar? Varför skulle jag vilja lära mig mer om det? – Detta är frågor som jag ställde när jag för första gången introducerades till RabbitMQ. Jag heter Gabor och är nu RabbitMQ-ingenjör och konsult. Under min tid med RabbitMQ har jag lärt mig att även erfarna kunder ställer dessa frågor.

TL;DR > Kolla in vår RabbitMQ-produktsida för användningsfall, funktioner och för att kontakta våra expertkonsulter.

Vilket problem löser RabbitMQ?

För att vi ska kunna fördjupa oss i vad RabbitMQ är och hur man använder det, är det värt att lära sig mer om själva problemområdet. Kommunikation mellan olika tjänster (a.k.a. datorer) är ett urgammalt problem.

Å ena sidan finns det olika protokoll som definierar transportmedlet och egenskaperna hos kommunikationen. Några exempel på sådana protokoll är SMTP, FTP, HTTP eller WebSockets (för att nämna några), som alla bygger på TCP/UDP. De handlar om formatering, tillförlitlighet och att hitta rätt mottagare av ett meddelande.

Å andra sidan kan vi utforska kommunikationen ur meddelandets perspektiv. Det existerar i ett system, sedan transporteras det till ett annat, omvandlas, det vill säga det har en livscykel. När det transporteras från ett system till ett annat bör vi vara medvetna om var meddelandet befinner sig och vem som äger det vid varje given tidpunkt.

De kommunikationsprotokoll som nämns ovan kan se till att äganderätten (och den ”fysiska” platsen) till meddelandet överförs från ett system till ett annat (även om det kan ta en viss tid att utföra denna transaktion). Vi kan betrakta överföringen som en transaktion mellan de två parterna medan båda är närvarande. För det mesta är detta aktiva utbyte önskvärt, t.ex. om man frågar efter tjänstens status och förväntar sig ett snabbt och korrekt svar. Ett exempel från den fysiska världen skulle vara att ringa någon över telefon:
1) vi startar samtalet,
2) väntar på att den andra parten ska svara,
3) har en trevlig diskussion,
4) lägger på luren.

Men det finns andra tillfällen då vi inte behöver svaret, utan bara att mottagaren ska ta över meddelandet och göra sitt jobb. I det här fallet behöver vi en förmedlande agent, ett annat system som tar över äganderätten till meddelandet (tillfälligt) och ser till att meddelandet når fram till sin destination. För att driva telefonexemplet vidare: den andra parten är inte tillgänglig för tillfället, så vi lämnar ett röstmeddelande. Telefonsvarartjänsten kommer att meddela den avsedda mottagaren.

Denna asynkrona (fördröjda) meddelandeöverföring är vad RabbitMQ tillhandahåller. Självklart kan den göra mer än en enkel telefonsvarare, så låt oss utforska några av de alternativ som den erbjuder nedan

(Om du är intresserad av att lära dig mer om RabbitMQs historia rekommenderar jag det första kapitlet i ”RabbitMQ in Action” av Alvaro Videla och Jason Williams. Det kommer att avslöja svaret på varför det är uppkallat efter kaniner).

RabbitMQ är en fri, öppen källkod och utbyggbar lösning för meddelandehantering (message queuing). Det är en meddelandeförmedlare som förstår AMQP (Advanced Message Queuing Protocol), men som också kan användas med andra populära meddelandeförmedlingslösningar som MQTT. Den är mycket tillgänglig, feltolerant och skalbar. Den är implementerad i Erlang OTP, en teknik som är skräddarsydd för att bygga stabila, tillförlitliga, feltoleranta och mycket skalbara system som har en inbyggd förmåga att hantera ett mycket stort antal samtidiga operationer, vilket är fallet med RabbitMQ och andra system som WhatsApp, MongooseIM, för att nämna några.

På en mycket hög nivå är det ett middleware-lager som gör det möjligt för olika tjänster i din applikation att kommunicera med varandra utan att behöva oroa sig för förlust av meddelanden samtidigt som det ger olika krav på tjänstekvalitet (QoS). Det möjliggör också finkornig och effektiv meddelandehantering som möjliggör omfattande frikoppling av applikationer.

Användningsfall

För att visa upp mångsidigheten hos RabbitMQ kommer vi att använda oss av tre fallstudier som visar hur RabbitMQ lämpar sig väl som en svart låda för hanterade tjänster, som en som integreras tätt med applikationen vilket möjliggör en väl fungerande mikrotjänstarkitektur, eller som en gateway till andra äldre projekt.

RabbitMQ som allmän meddelandebuss

När ett monolit-system bryts ner till separata delsystem är ett av de största problemen som måste lösas vilken kommunikationsteknik som ska användas. En lösning som Mulesoft eller MassTransit kan ”koppla ihop” tjänster genom att deklarera HTTP-lyssnare och -avsändare. Denna typ av lösning behandlar RabbitMQ som en svart låda, men kan ändå utnyttja RabbitMQ:s möjligheter. Som ett exempel på direkt kommunikation kan vi använda HTTP för att ”ansluta” de enskilda tjänsterna. Även om det är ett välunderstött och solitt val har det några nackdelar:
1) Upptäckten av tjänsterna är inte löst. En möjlig lösning är att använda DNS. I takt med att systemet skalar och växer ökar också komplexiteten i att hitta och balansera denna belastning. RabbitMQ kan mildra lösningens ökade komplexitet.
2) Kommunikationen är flyktig. Meddelanden är benägna att tappas bort eller dupliceras på nätverkslagret. Om en tjänst är tillfälligt otillgänglig misslyckas leveransen.

RabbitMQ kan hjälpa till i båda fallen genom att utnyttja meddelandeköer som transportmedel. Tjänsterna kan publicera och konsumera meddelanden, vilket frikopplar slut-till-slut-meddelandetransporten från tillgängligheten hos måltjänsten. Om en konsumerande tjänst är tillfälligt otillgänglig, till skillnad från HTTP, buffras och behålls meddelandet på ett säkert sätt i RabbitMQ och levereras så småningom när tjänsten är online igen.

Det är också enklare att hitta meddelandet. Allt vi behöver veta är var RabbitMQ finns och vad könamnet är. Även om det verkar som om detta bara uppfinner problemet på nytt är detta skalbart. Könamnet fungerar som tjänstens adress. De enskilda tjänsternas konsumtion av meddelanden från köerna erbjuder ett medel för skalbarhet, dvs. varje kö kan betjäna flera konsumenter och balansera belastningen. Det finns inget behov av att ändra den kökonfiguration som redan är inbyggd i tjänsterna.

Denna måttligt statiska kökonfiguration skjuter RabbitMQ till ett middleware-skikt där en solid design kan garantera en stabil tjänstekvalitet på lång sikt.

RabbitMQ som ett avancerat routningsskikt för mikrotjänster

I den andra änden av spektrumet finns en arkitektur som är mer flytande och som anpassar sig till de ständigt föränderliga behoven hos många mikrotjänster. Det som får RabbitMQ att glänsa i den här miljön är de mycket kraftfulla routningsmöjligheterna.

Routningslogiken implementeras i olika (så kallade) utbytestyper som dynamiskt kan skapas av applikationen vid behov. Destinationstjänsterna skapar de köer som de vill konsumera från och binder dem sedan till utbyten genom att ange ett mönster för de nycklar som utgivarna kan använda när de publicerar meddelandet. (Tänk på dessa nycklar som metadata som förmedlingarna kan använda för att dirigera och leverera meddelanden till en eller flera köer.)

Ruttningslogiken implementeras i olika (s.k.) förmedlingstyper som dynamiskt kan skapas av programmet vid behov. Destinationstjänsterna skapar de köer som de vill konsumera från och binder dem sedan till utbyten genom att specificera ett mönster för de nycklar som utgivarna kan använda när de publicerar meddelandet. (Tänk på dessa nycklar som metadata som förmedlingarna kan använda för att dirigera och leverera meddelanden till en eller flera köer.)

RabbitMQ har fyra användbara förmedlingstyper som täcker de flesta användningsområden för meddelandehantering:
1) Direkt förmedling. Detta kommer att leverera det inkommande meddelandet till vilken kö som helst vars bindningsnyckel exakt matchar meddelandets routningsnyckel. Om du binder köerna med könamnet som routningsnycklar kan du se det som en en-till-en-meddelandeöverlämning. Det är enkelt att leverera samma meddelande till flera köer genom att använda bindningsnycklar för flera köer.
2) Ämnesutbyte. Detta kommer att leverera det inkommande meddelandet till alla köer vars wildcard-bindningsnyckel matchar routningsnyckeln för det publicerade meddelandet. Bindningsnycklar kan innehålla wildcard-matchningskriterier för en sammansatt routningsnyckel. (t.ex. kommer bindningsnyckeln logs.*.error att matcha routningsnycklarna logs.accounting.error och logs.ui.error). Detta gör det möjligt för oss att skriva enkla tjänster där logiken är väl avgränsad, och meddelandet kommer att nå rätt tjänster genom RabbitMQ:s ”magi”.
3) Fanout-utbyte. Vissa meddelanden måste levereras till alla köer, det är här som en fanout exchange kan användas istället för att skriva en utarbetad multicastlogik i applikationen. Med en RabbitMQ fanout exchange binder varje tjänst lämplig kö till exchange utan att behöva ange en bindningsnyckel, och allt sker automatiskt. Om en bindningsnyckel specificeras kommer fanout exchange helt enkelt att ignorera den och fortfarande dirigera/spridda meddelanden till alla köer som är bundna till den.
4) Headers exchange (utbyte av rubriker). Det här utbytet utnyttjar AMQP-meddelandets struktur och kan göra komplexa routningar baserade på AMQP-meddelandets rubriker (inklusive anpassade rubriker). Headers är metadata som bifogas varje meddelande som skickas via AMQP.

Förutom utbyten finns det andra användbara funktioner i RabbitMQ som gör det möjligt att implementera mycket komplex logik för meddelandehantering. Några av de viktigaste funktionerna är:
1) Anpassade insticksprogram. RabbitMQ kan utvidgas genom att användarna kan lägga till plugins. Nästan varje aspekt av RabbitMQ kan anpassas, inklusive hantering, autentisering och auktorisering, back-up-lösningar och klusterbildning.
2) Klusterbildning. När en enda RabbitMQ-server inte räcker till kan flera RabbitMQ-mäklare anslutas för att arbeta tillsammans och skala systemet. Det kan göra det möjligt för RabbitMQ att behandla fler meddelanden eller öka motståndskraften mot fel.
3) Inställning av tjänstekvalitet. Tidskänslig leverans av meddelanden kan underlättas genom att ett TTL-värde (Time-to-Live) kopplas till antingen meddelandet eller kön. Meddelanden med tidsbegränsning kan automatiskt levereras till en Dead-letter-kö. Genom att kombinera vanlig routinglogik och dessa extra funktioner kan man skapa mycket avancerade routinglogiker. En annan användbar funktion är att använda prioriterade köer där utgivaren kan tilldela varje meddelande en prioritetsnivå. Det är också möjligt att begränsa antalet obekräftade meddelanden, vilket gör det möjligt att trimma prestandan för de konsumerande tjänsterna, i det här fallet tillämpar RabbitMQ en back-pressure-mekanism.

RabbitMQ integreras i äldre system

I det föregående användningsfallet nämnde jag möjligheten att använda insticksprogram (plug-ins) för att utöka funktionaliteten hos RabbitMQ. Denna kraftfulla funktion gör det möjligt för RabbitMQ att fungera som ett förmedlingslager mellan dina RabbitMQ-nativa (AMQP-kompatibla) tjänster och andra äldre program. Några anmärkningsvärda exempel är:
1) Användning av RabbitMQ som en MQTT-mäklare genom att helt enkelt aktivera en plug-in. Detta öppnar landskapet för många IoT-tekniker.
2) RabbitMQ:s JMS-plugin (Java Message Service), som gör det möjligt för RabbitMQ att kommunicera med vilken JMS-kompatibel meddelandehantering som helst.
3) Om din applikation använder ett proprietärt protokoll för att kommunicera är det möjligt att utveckla ett anpassat plugin för att ansluta till sådana tjänster.

Slutsats

Som exemplen ovan visar finns det knappast någonting som RabbitMQ inte kan kommunicera med. Men som med allt i livet har det ett pris. Även om konfigureringen av RabbitMQ för det mesta är okomplicerad kan ibland bara antalet funktioner vara överväldigande. Om du stöter på problem med att utforma, implementera eller stödja dina RabbitMQ-mäklare kan du kontakta vårt expertteam här. Eller om du vill kickstarta din karriär inom en av de mest efterfrågade teknikerna, anmäl dig till vår 3-dagars RabbitMQ-utbildning.

Debugging RabbitMQ

Vill du ha ett intuitivt system som gör övervakning och underhåll av din RabbitMQ enkelt? Få din gratis 45-dagars testversion av WombatOAM nu.

Vår sida om RabbitMQ-funktioner