Waarom Rabbit? Wat is MQ? Hoe kan het onze applicaties verbeteren? Waarom zou ik er meer over willen leren? – Dit zijn vragen die ik me stelde toen ik voor het eerst kennismaakte met RabbitMQ. Ik ben Gabor, en ik ben nu een RabbitMQ ingenieur en consultant. In de tijd dat ik met RabbitMQ werk, heb ik geleerd dat zelfs ervaren klanten deze vragen stellen.
TL;DR > Bekijk onze RabbitMQ product pagina voor use cases, features en om contact op te nemen met onze expert consultants.
Welk probleem lost RabbitMQ op?
Voordat we ons gaan verdiepen in wat RabbitMQ is en hoe je het kunt gebruiken, is het de moeite waard om meer te leren over het probleem domein zelf. Communicatie tussen verschillende diensten (a.k.a computers) is een eeuwenoud probleem.
Aan de ene kant zijn er de verschillende protocollen die de wijze van transport en de eigenschappen van de communicatie definiëren. Voorbeelden van dergelijke protocollen zijn SMTP, FTP, HTTP of WebSockets (om er een paar te noemen), die alle zijn gebaseerd op TCP/UDP. Zij houden zich bezig met de opmaak, de betrouwbaarheid en het vinden van de juiste ontvanger van een bericht.
Aan de andere kant kunnen we de communicatie onderzoeken vanuit het perspectief van het bericht. Het bestaat in één systeem, dan wordt het getransporteerd naar een ander, wordt getransformeerd, dat wil zeggen, het heeft een levenscyclus. Terwijl het van het ene systeem naar het andere reist, moeten we ons ervan bewust zijn waar het bericht zich bevindt, en wie er op een bepaald moment de eigenaar van is.
De bovengenoemde communicatieprotocollen kunnen ervoor zorgen dat het eigendom (en de “fysieke” locatie) van het bericht van het ene systeem naar het andere wordt overgedragen (hoewel het enige tijd kan duren om deze transactie uit te voeren). We kunnen de overdracht beschouwen als een transactie tussen de twee partijen terwijl beide aanwezig zijn. Meestal is deze actieve uitwisseling wenselijk, bv. het vragen naar de status van de dienst en het verwachten van een tijdig en accuraat antwoord. Een voorbeeld uit de fysieke wereld is iemand bellen over de telefoon:
1) we beginnen het gesprek,
2) wachten tot de andere partij antwoordt,
3) hebben een leuk gesprek,
4) hangen de telefoon op.
Maar er zijn andere momenten waarop we het antwoord niet nodig hebben, we hebben alleen de ontvanger nodig om het bericht in ontvangst te nemen en zijn werk te doen. In dat geval hebben we een intermediaire agent nodig, een ander systeem dat (tijdelijk) eigenaar is van het bericht en ervoor zorgt dat het bericht zijn bestemming bereikt. Om nog een voorbeeld te geven: de andere partij is op dit moment niet bereikbaar, dus laten we een voicemailbericht achter. De voicemail dienst zal de beoogde ontvanger op de hoogte stellen.
Deze asynchrone (vertraagde) bericht aflevering is wat RabbitMQ biedt. Het is duidelijk dat het meer kan dan een eenvoudig antwoordapparaat, dus laten we een aantal van de opties die het biedt hieronder verkennen
(Als u geïnteresseerd bent om meer te leren over de geschiedenis van RabbitMQ, raad ik u het eerste hoofdstuk van “RabbitMQ in Action” door Alvaro Videla en Jason Williams aan. Het zal het antwoord onthullen op de vraag waarom het naar konijnen is vernoemd).
RabbitMQ is een gratis, open-source en uitbreidbare message queuing oplossing. Het is een message broker die AMQP (Advanced Message Queuing Protocol) begrijpt, maar is ook in staat om te worden gebruikt met andere populaire messaging oplossingen zoals MQTT. Het is zeer beschikbaar, fouttolerant en schaalbaar. Het is geïmplementeerd in Erlang OTP, een technologie op maat voor het bouwen van stabiele, betrouwbare, fouttolerante en zeer schaalbare systemen die native mogelijkheden bezitten om zeer grote aantallen gelijktijdige operaties af te handelen, zoals het geval is met RabbitMQ en andere systemen zoals WhatsApp, MongooseIM, om er een paar te noemen.
Op een zeer hoog niveau is het een middleware laag die het mogelijk maakt dat verschillende diensten in uw applicatie met elkaar kunnen communiceren zonder zich zorgen te maken over het verlies van berichten, terwijl verschillende kwaliteit van de dienstverlening (QoS) vereisten worden geboden. Het maakt ook fijnkorrelige en efficiënte bericht routing mogelijk, waardoor uitgebreide ontkoppeling van applicaties mogelijk wordt.
Gebruikssituaties
Om de veelzijdigheid van RabbitMQ te laten zien, gaan we drie case studies gebruiken die laten zien hoe RabbitMQ zeer geschikt is als een black-box managed service benadering, als een die nauw integreert met de applicatie waardoor een goed functionerende micro-service architectuur mogelijk wordt, of als een gateway naar andere legacy projecten.
RabbitMQ als een algemene berichten-bus
Wanneer een monolith systeem wordt opgesplitst in afzonderlijke subsystemen, is een van de grootste problemen die moeten worden opgelost welke communicatietechnologie moet worden gebruikt. Een oplossing zoals Mulesoft, of MassTransit kan diensten “bekabelen” door HTTP luisteraars en verzenders te declareren. Dit soort oplossing behandelt RabbitMQ als een black box, maar is nog steeds in staat om gebruik te maken van de mogelijkheden van RabbitMQ. Als voorbeeld van directe communicatie, laten we HTTP gebruiken om de individuele services te “verbinden”. Hoewel het een goed ondersteunde en solide keuze is, heeft het enkele nadelen:
1) Het ontdekken van services is niet opgelost. Een mogelijke oplossing is om DNS te gebruiken. Als het systeem schaalt en groeit, neemt ook de complexiteit van het vinden en balanceren van deze belasting toe. RabbitMQ kan de toegenomen complexiteit van de oplossing beperken.
2) De communicatie is vluchtig. Berichten zijn vatbaar om te worden gedropt of gedupliceerd op de netwerk laag. Als een dienst tijdelijk niet beschikbaar is, mislukt de aflevering.
RabbitMQ kan in beide gevallen helpen door gebruik te maken van berichtwachtrijen als transportmiddel. Diensten kunnen berichten publiceren en consumeren, waardoor de end-to-end levering van berichten wordt ontkoppeld van de beschikbaarheid van de bestemmingsdienst. Als een consumerende dienst tijdelijk niet beschikbaar is, wordt het bericht, in tegenstelling tot HTTP, veilig gebufferd en bewaard in RabbitMQ, en uiteindelijk afgeleverd wanneer de dienst weer online komt.
Ontdekbaarheid is ook vereenvoudigd. We hoeven alleen maar te weten waar RabbitMQ zich bevindt en wat de naam van de wachtrij is. Hoewel het lijkt alsof hiermee het probleem opnieuw wordt uitgevonden, is dit schaalbaar. De naam van de wachtrij fungeert als het adres van de service. Het consumeren van berichten uit de wachtrijen door de individuele diensten biedt een middel voor schaalbaarheid, d.w.z. elke wachtrij kan meerdere consumenten bedienen en de belasting balanceren. Het is niet nodig om de wachtrij-configuratie te veranderen die al in de services is ingebouwd.
Deze matig statische wachtrij-configuratie duwt RabbitMQ naar een middleware laag waar een solide ontwerp een stabiele service kwaliteit op de lange termijn kan garanderen.
RabbitMQ als een geavanceerde routing laag voor micro-services
Aan de andere kant van het spectrum staat een architectuur die meer vloeiend is en zich aanpast aan de steeds veranderende behoeften van veel micro-services. Wat RabbitMQ in deze omgeving doet schitteren, zijn de zeer krachtige routeringsmogelijkheden die het biedt.
De routeringslogica is geïmplementeerd in verschillende (zogenaamde) uitwisselingstypen die dynamisch door de applicatie kunnen worden aangemaakt wanneer dat nodig is. De bestemmingsdiensten creëren de wachtrijen waarvan zij willen consumeren, en binden deze dan aan exchanges door een patroon te specificeren voor de sleutels die de uitgevers kunnen gebruiken bij het publiceren van het bericht. (Denk aan deze sleutels als metadata die de exchanges kunnen gebruiken om de berichten te routeren en af te leveren aan een of meer wachtrijen.)
De routing logica is geïmplementeerd in verschillende (zogenaamde) exchange types die dynamisch kunnen worden aangemaakt door de applicatie wanneer dat nodig is. De bestemmingsdiensten creëren de wachtrijen waarvan zij willen consumeren, en binden deze dan aan uitwisselingen door een patroon te specificeren voor de sleutels die de uitgevers kunnen gebruiken bij het publiceren van het bericht. (Zie deze sleutels als metadata die de exchanges kunnen gebruiken om berichten te routeren en af te leveren bij een of meer wachtrijen.)
RabbitMQ wordt geleverd met vier nuttige uitwisselingstypen die de meeste gebruikscases voor berichtenuitwisseling dekken:
1) Directe uitwisseling. Hierbij wordt het inkomende bericht afgeleverd bij elke wachtrij waarvan de bindingssleutel exact overeenkomt met de routingsleutel van het bericht. Als u de wachtrijen bindt met de wachtrijnaam als routeringssleutel, dan kunt u het zien als een één-op-één berichtaflevering. Het is eenvoudig om hetzelfde bericht aan meerdere wachtrijen af te leveren door de bindingssleutels voor meerdere wachtrijen te gebruiken.
2) Onderwerp uitwisseling. Dit zal het inkomende bericht afleveren aan elke wachtrij waarvan de wild-card bindingssleutel overeenkomt met de routingsleutel van het gepubliceerde bericht. Bindingssleutels kunnen wild-card overeenkomende criteria voor een samengestelde routingsleutel bevatten. (b.v. de bindingssleutel logs.*.error
zal overeenkomen met de routingsleutels logs.accounting.error
en logs.ui.error
). Dit stelt ons in staat om eenvoudige services te schrijven waar de logica goed is ingeperkt, en het bericht zal aankomen bij de juiste services door de “magie” van RabbitMQ.
3) Fanout uitwisseling. Sommige berichten moeten worden afgeleverd bij alle wachtrijen, dit is waar een fanout exchange kan worden gebruikt in plaats van het schrijven van een uitgebreide multicast logica in de applicatie. Met een RabbitMQ fanout uitwisseling bindt elke dienst de juiste wachtrij aan de uitwisseling zonder dat het nodig is om een bindingssleutel te specificeren, en het gebeurt allemaal automatisch. Als een bindingssleutel is gespecificeerd, zal de fanout uitwisseling deze gewoon negeren en nog steeds berichten routeren/uitzenden naar alle wachtrijen die eraan zijn gebonden.
4) Headers uitwisseling. Deze uitwisseling maakt gebruik van de structuur van AMQP-berichten en is in staat tot complexe routering op basis van de headers (inclusief aangepaste headers) van het AMQP-bericht. Headers zijn metadata die zijn gekoppeld aan elk bericht dat via AMQP wordt verzonden.
Naast uitwisselingen, zijn er andere nuttige functies in RabbitMQ die de implementatie van zeer complexe berichtenlogica mogelijk maken. Enkele van de belangrijkste functies zijn:
1) Custom plug-ins. RabbitMQ is uitbreidbaar door gebruikers de mogelijkheid te bieden plug-ins toe te voegen. Bijna elk aspect van RabbitMQ is aanpasbaar, inclusief het beheer, de authenticatie en autorisatie, back-up oplossingen, en clustering.
2) Clustering. Wanneer een enkele RabbitMQ server niet genoeg is, kunnen meerdere RabbitMQ brokers worden aangesloten om samen te werken en het systeem te schalen. Het kan RabbitMQ in staat stellen om meer berichten te verwerken of de bestendigheid tegen fouten te vergroten.
3) Quality of Service tuning. Tijd-gevoelige bericht aflevering kan worden geholpen door een TTL (Time-to-Live) waarde aan het bericht of de wachtrij te koppelen. Berichten waarvan de tijd is verstreken kunnen automatisch worden afgeleverd in een wachtrij met een dode letter. Het combineren van gewone routing logica en deze extra mogelijkheden kan leiden tot zeer geavanceerde routing logica. Een andere nuttige functie is het gebruik van prioriteitswachtrijen waarbij de uitgever aan elk bericht een prioriteitsniveau kan toekennen. Het is ook mogelijk om het aantal unacknowled berichten te limiteren, waarmee de performance van de consumerende services kan worden getuned, in dit geval past RabbitMQ een back-pressure mechanisme toe.
RabbitMQ geïntegreerd in legacy systemen
In de vorige use-case noemde ik de mogelijkheid om plug-ins te gebruiken om de functionaliteit van RabbitMQ uit te breiden. Deze krachtige mogelijkheid maakt het mogelijk om RabbitMQ te gebruiken als een bemiddelingslaag tussen uw RabbitMQ native (AMQP capable) services en andere legacy applicaties. Enkele opmerkelijke voorbeelden zijn:
1) RabbitMQ gebruiken als een MQTT broker door simpelweg een plug-in in te schakelen. Dit opent het landschap voor veel IoT-technologieën.
2) RabbitMQ’s JMS (Java Message Service) plug-in, waarmee RabbitMQ kan communiceren met elke JMS capabele messaging-oplossing.
3) Als uw applicatie een eigen protocol gebruikt voor communicatie, is het mogelijk om een aangepaste plug-in te ontwikkelen om verbinding te maken met dergelijke services.
Conclusie
Zoals de bovenstaande voorbeelden laten zien, is er bijna niets waarmee RabbitMQ niet kan communiceren. Maar zoals met alles in het leven, heeft het een prijs. Hoewel het configureren van RabbitMQ meestal recht-toe-recht-aan is, kan het aantal mogelijkheden soms overweldigend zijn. Als u problemen ondervindt bij het ontwerpen, implementeren of ondersteunen van uw RabbitMQ brokers, neem dan hier contact op met ons expert team. Of, als u uw carriere wilt starten in een van de meest gevraagde technologieen schrijf u dan in voor onze 3-daagse RabbitMQ training cursus.
Debugging RabbitMQ
Wilt u een intuitief systeem dat monitoring en onderhoud van uw RabbitMQ eenvoudig maakt? Neem dan nu uw gratis 45 dagen proefversie van WombatOAM.
Onze RabbitMQ Mogelijkheden pagina