Zpět

RabbitMQ – implementace message brokera

5 minut čtení 01. 07. 2021

RabbitMQ

Message broker

Message broker je software, který dovoluje, jak už název vypovídá, různým aplikacím či službám komunikovat a vyměňovat si mezi sebou informace. Tyto brokery využívají ke komunikaci různých protokolů (např. AMQP), což dovoluje aplikacím být na sobě nezávislé a komunikovat mezi sebou i přes to, že jsou napsány v různých jazycích či běží na rozdílných strojích.

Message brokery tvoří tzv. prostředníka mezi ostatními aplikacemi a poskytují možnost odeslat jakoukoliv zprávu bez nutné znalosti komu je zpráva odeslána, jestli a jak bude zpracována či kolik takových příjemců existuje.

Jednou z hlavních částí těchto brokerů je message queue, která ukládá a řadí příchozí zprávy, dokud je cílová aplikace není schopna přijmout. Zprávy si tedy zachovávají přesně takové pořadí, v jakém je zdrojová aplikace odeslala.

RabbitMQ

Jednou z implementací message brokera je RabbitMQ, který aktuálně podporuje několik komunikačních protokolů, jako například AMQP, MQTT, STOMP aj.

RabbitMQ je vysoce dostupný, škálovatelný a lze jej dostatečně nakonfigurovat ke splnění požadavků na službu. Též nabízí vlastní management rozhraní, díky kterému lze celého brokera ovládat či monitorovat. Pro práci s brokerem existují různé knihovny pro mnoho programovacích jazyků. My se budeme v dnešním článku zabývat hlavně komunikací přes samostatné queue a následně přes exchange.

Jako první si vysvětlíme jednotlivé pojmy, které budeme dále používat.

  • Message – balík informací, který se skládá z hlavičky (header) nesoucí metadata zprávy a samotného obsahu zprávy (body).
  • Producer – aplikace, která vytváří a odesílá message.
  • Consumer – aplikace, která přijímá a zpracovává message.
  • Queue – komunikační kanál mezi producerem a consumerem.
  • Exchange – odděluje queue od producera. V takovém případě producer neví o cílových frontách, pouze message odešle právě do exchange, který na základě určitého klíče předá zprávu všem potřebným frontám.
  • Routing key – díky tomuto klíči je schopen exchange odeslat message těm správným consumerům.
  • Binding key – definuje vazbu mezi consumerem a exchange. Těchto klíčů může být 0 – N, a na základě kombinace tohoto klíče s routing key exchange rozhodne, zda má být message předána právě tomuto consumerovi.

Pro názorovou ukázku dále uvažujme, že je naše aplikace rozdělena na jednotlivé mikroslužby, které musí mezi sebou komunikovat. Následně si proto popíšeme, jak by taková komunikace probíhala v případě využití právě queue a exchange.

Queue

Nejjednodušším způsobem komunikace je využití „holé“ fronty. Princip spočívá v tom, že jedna ze služeb (v tomto případě producer) vytvoří zprávu a odešle ji do fronty. Na stejnou frontu je napojená druhá služba (consumer), která čeká na jakoukoliv zprávu přijatou z této fronty, a tu poté zpracuje.

RabbitMQ - Queue

Samotné fronty lze různě konfigurovat. Můžeme například nastavit ukládání zpráv takovým způsobem, dokud některý z consumerů tuto zprávu neoznačí za přijatou, resp. zpracovanou. Tímto nastavením se vyvarujeme případné ztrátě zpráv v případě, kdy dojde k neočekávanému výpadku některé ze služeb.

Stejně tak, jako může do fronty posílat zprávy více producerů, může i více consumerů tyto zprávy zpracovávat. Na základě toho můžeme nastavit různá chování těchto consumerů.

RabbitMQ - Queue

Ať už jde o zpracování jedné zprávy odeslané do fronty všemi consumery nebo dále možnost mezi všechny consumery rozložit zátěž zpracování zpráv – tzn., že pokud první consumer již zprávu zpracovává a ve frontě se objeví zpráva další, je tato předána jinému volnému consumerovi.

Exchange

Pokud nám komunikace za pomoci jednoduchých front nestačí, můžeme využít již zmíněných služeb exchange. Co si ale pod pojmem exchange představit?

V reálném světě jej lze přirovnat k často využívanému odběru novinek, které nabízí všemožné portály. Tzn. že my jako odběratelé se zavážeme k odběru těchto novinek na základě určitých preferencí. Následně dojde ke vzniku novinky s určitou povahou (typem), kterou portál (můžeme si jej představit jako producer) odešle na jiný server a dále neřeší, komu má jaký email odeslat. Tento server zastává tedy roli exchange a na základě našich preferencí (consumer preferencí) nám patřičné emaily rozešle.

Existuje několik typů exchange:

  1. Fanout
    Je nejjednodušším typem exchange, který všechny do něj odeslané zprávy předá každé frontě (consumerovi) bez ohledu na nějaká pravidla. Zde jako consumer stačí vytvořit tzv. binding key mezi vytvořenou frontou a exchange.
    RabbitMQ - Fanout
  2. Direct
    Tento typ, na rozdíl od předchozího, bude při vytváření spojení mezi frontou consumera a exchange využívat jak binding key, tak routing key. Jako routing key si můžeme představit právě typ vyprodukované zprávy. V případě producera je routing key předáváno vždy. Tzn., že je zpráva předána pouze těm frontám (consumerům), kteří uvedli totožný klíč.RabbitMQ - DirectZ obrázku si můžeme povšimnout, že druhý consumer naslouchá na dva routing keys (black, green). Tzn., že při provádění bindingu můžeme uvádět až N-klíčů.
  3. Topic
    Dle mého nejzajímavějším typem exchange je topic 🙂 Funguje na podobném principu jako typ direct, ale s tím rozdílem, že routing key je rozdělen na logické části oddělené tečkou (např. news.sport.football). Binding key může pak představovat buď kompletní routing key nebo může využívat tzv. wildcards, které dokáží nahrazovat části routing key.

    *
    (hvězdička) – nahrazuje přesně jedno slovo
    # (hashtag) – nahrazuje žádné nebo N-slovRabbitMQ - TopicJak je znázorněno na obrázku výše, pokud routing key bude color.orange.new, bude zpráva předána prvnímu consumerovi (Q1). A to proto, že tento routing key splňuje formát s wildcards uvedený právě v binding key. Naopak, pokud routing key bude lazy.create.center.employee, půjde zpráva do druhého consumera (Q2).
  4. Headers
    Pokud nám nevyhovují routing keys, můžeme využít typ headers. Ten routing key ignoruje a namísto toho při rozhodování, kterým consumerům zprávu předá, využívá hlaviček ze zprávy.

    • type = error
    • application = web
    • x-match = all

    Hlavička x-match může nabývat dvou hodnot – all nebo any. V případě „all“ je potřeba, aby všechny hlavičky seděly s hlavičkami uvedenými při bindování fronty consumera. Jakmile alespoň jedna nesedí, consumer zprávu nedostane.
    Naopak v případě „any“ stačí, aby se shodovala alespoň jedna z hlaviček. V takovém případě pak consumer zprávu obdrží.

Závěr

Cílem tohoto článku bylo se primárně seznámit s message brokery jako takovými, a také si přiblížit základní prvky implementace s RabbitMQ.

Samozřejmě způsobů, jak využít message brokery je mnoho. Proto se v dalším pokračování zaměříme na možnosti využití již zmiňovaného exchange, a přiblížíme si ještě o něco více právě užití typu topic.

Sledujte nás i nadále! 🙂

Zdroj: www.rabbitmq.com

Hledáš nové uplatnění? Nabíráme!

KARIÉRA V B2A