RabbitMQ to doskonały projekt open-source, który pozwala szybko i sprawnie dostarczać setki tysięcy wiadomości na sekundę do Twojej aplikacji. Poniższy wpis przedstawia sposób, w jaki można umieścić Klaster RabbitMQ składający się z trzech oddzielnych hostów. W tym celu użyjemy Dockera i połączymy się z gotowym klastrem za pomocą węzła.js.

o RabbitMQ

RabbitMQ to system kolejkowy oparty na protokole AMQP, sam system został napisany w Erlangu. Dzięki zastosowaniu tego języka RabbitMQ idealnie nadaje się do zastosowania jako centralna szyna danych w architekturze mikroserwisów. Taka szyna stanowi świetne podłoże dla aplikacji pozwalających na duży zakres dynamiczny rozwoju w paradygmacie DDD i CQRS. Ponieważ szyna danych (Kolejka wiadomości) jest szkieletem architektury, ważne jest, aby była zawsze dostępna i odporna na awarie. Redundantna architektura staje się naturalnym wyborem, tj. replikacja danych do oddzielnych węzłów wykonawczych.

replikacja w RabbitMQ jest obsługiwana natywnie w trybie master-slave. Oznacza to, że RabbitMQ zawsze wybierze jeden węzeł dla każdej utworzonej kolejki i przekieruje wszystkie wiadomości do niej w celu zapisania, a także pobierze z niej Wiadomości do odczytu z kolejki, pozostałe węzły (Slave) działają jako replikator danych gotowy przejąć rolę głównego węzła przez cały czas. Chociaż największym sensem jest replikacja, gdy węzły są rozproszone na różnych maszynach fizycznych, w tym przypadku użyję przykładu replikacji w tej samej maszynie. RabbitMQ ze względu na swój cel – czyli setki tysięcy obsługiwanych wiadomości na sekundę, nie jest preferowany w trybie replikacji na maszynach, które nie są w tej samej szafie serwerowej. Wynika to z faktu, że wiadomości pozostają w kolejce bardzo krótko i założenia nie powinny wykraczać poza RAM, replikować je w oparciu o połączenie sieciowe w innej części centrum danych lub do zupełnie innego centrum danych oznaczałoby drastyczne spadki wydajności, a w tej klasie systemu nie można sobie pozwolić. Dodatkowo umieszczając węzły RabbitMQ blisko siebie minimalizujemy ryzyko tzw. partycji sieciowej (co jest bardzo mało prawdopodobne w przypadku jednej ruletki), czyli zjawiska przerywania komunikacji między węzłami w taki sposób, że co najmniej 2 węzły z całego klastra uznają się za master. Więcej o partycji sieciowej w kontekście RabbitMQ można przeczytać tutaj.

w związku z tym regułą opartą na praktyce jest umieszczenie RabbitMQ w trybie replikacji tylko w tym samym centrum danych.

Pobieranie obrazów Dockera

zakładam, że wiesz co to jest Docker i jak go używać, ponieważ w następnej części wpisu będziemy go używać szeroko

na początek zacznij od pobrania odpowiednich obrazów RabbitMQ (wraz z wtyczką panelu administracyjnego) i węzła.js, w tym celu używamy następujących poleceń:

docker pull 3.6.6-managementdocker pull node:11.10.1

Setup RabbitMQ hosts

na potrzeby prezentacji uruchomimy jeden obraz RabbitMQ, do którego połączymy się poleceniem docker exec i wywołamy powłokę bash, aby móc uruchomić konfigurację na swój sposób. Użyjmy polecenia:

docker run --hostname rabbit --name rabbit --rm -ti --net="host" rabbitmq:3.6.6-management /bin/bash

powyższe polecenie uruchomi obraz z RabbitMQ, który zostanie usunięty po opuszczeniu powłoki. Instancja zostanie podłączona do naszego interfejsu sieciowego, więc nie musimy się martwić o przekierowanie portów. Jeśli powłoka [email protected]:/# pojawiła się naszym oczom, oznacza to, że wszystko poszło dobrze.

następnym krokiem jest uruchomienie trzech procesów RabbitMQ na oddzielnych portach, każdy proces otrzyma unikalną nazwę.

RABBITMQ_NODE_PORT=5672 RABBITMQ_SERVER_START_ARGS="-rabbitmq_management listener " RABBITMQ_NODENAME=rabbit rabbitmq-server -detachedRABBITMQ_NODE_PORT=5673 RABBITMQ_SERVER_START_ARGS="-rabbitmq_management listener " RABBITMQ_NODENAME=hare rabbitmq-server -detachedRABBITMQ_NODE_PORT=5674 RABBITMQ_SERVER_START_ARGS="-rabbitmq_management listener " RABBITMQ_NODENAME=john rabbitmq-server -detached

następnie, za pomocą rabbitmqctl, dołączamy oba węzły do roota o nazwie rabbit:

rabbitmqctl -n hare stop_apprabbitmqctl -n hare join_cluster [email protected]`hostname -s`rabbitmqctl -n hare start_apprabbitmqctl -n john stop_apprabbitmqctl -n john join_cluster [email protected]`hostname -s`rabbitmqctl -n john start_app

w końcu możemy otworzyć przeglądarkę i wprowadzić adres http://localhost:15672, aby sprawdzić, czy wszystko poszło dobrze, konsola zarządzania klastrem powinna wskazywać na wszystkie węzły jak na poniższym ekranie.

ważne. Nie wyłączaj powłoki kontenera z RabbitMQ, ponieważ spowoduje to jej usunięcie (opcja –rm w poleceniu uruchamiania dokera)

mamy ostatnią rzecz do zrobienia, chociaż klaster RabbitMQ jest gotowy, musimy skonfigurować odpowiednie polityki. Funkcja ta jest zaimplementowana za pomocą panelu administracyjnego, więcej informacji o wysokiej dostępności (HA) w RabbitMQ można przeczytać w dokumentacji.

powyższy przykład konfiguracji zasad HA. A poniżej jest metoda weryfikacji. Liczba +2 w nazwie węzła oznacza liczbę oddzielnych hostów, do których kolejka jest replikowana.

instalacja i pobieranie biblioteki amqp w węźle.js

następnym krokiem jest uruchomienie instancji kontenera Docker z węzłem.js image, w tym celu uruchom następujące polecenie, które również współdzieli interfejs sieciowy.

docker run -ti --rm --net="host" node:11.10.1 /bin/bash

następnie w miejscu wybranym przez naszą stronę (np. /home) tworzymy katalog, w którym umieszczamy niezbędne skrypty i instalujemy bibliotekę AMQP-connection-manager, która umożliwia połączenie z RabbitMQ (lub innym systemem implementującym protokół AMQP) z poziomu węzła.js.

npm install --save amqp-connection-manager

ponadto biblioteka Pozwala na dodanie kilku adresów hostów RabbitMQ zapewniając mechanizm ponownego połączenia w przypadku awarii dowolnego hosta. Jest to bardzo przydatna funkcjonalność, ponieważ dba o prawidłowe połączenie z RabbitMQ, a w przypadku awarii może wykryć wiadomości w pamięci, dopóki połączenie nie pojawi się z powrotem.

przykładowy kod producenta-konsumenta

teraz, gdy mamy przygotowane wszystkie komponenty, możemy zacząć tworzyć prosty kod odpowiedzialny za tworzenie i odbieranie wiadomości. W tym celu utworzymy dwa pliki i wypełnimy je kodem.

producent.js-skrypt łączy się z instancją RabbitMQ i zaczyna wysyłać 10 wiadomości na sekundę.

let q = 'tasks';let amqp = require('amqp-connection-manager');function sleep(ms) { if(ms setTimeout(resolve, ms));}let main = async () => { var connection = amqp.connect(); var channelWrapper = connection.createChannel({ json: true, setup: function(channel) { return channel.assertQueue(q, { durable: true }); } }); console.log('Starting message stream') while (true) { await channelWrapper.sendToQueue(q, { value: Math.random() }) await sleep(100) }}main()

js-skrypt łączy się z instancją RabbitMQ i rozpoczyna Odczyt wiadomości z kolejki.

let q = 'tasks';let amqp = require('amqp-connection-manager');let main = async () => { var connection = amqp.connect(); var channelWrapper = connection.createChannel({ json: true, setup: function(channel) { return channel.assertQueue(q, { durable: true }); } }); channelWrapper.addSetup(function(channel) { return Promise.all() });}main()

pliki utworzone w ten sposób mogą być uruchamiane oddzielnie za pomocą węzła.js i obserwuj, jak consumer.js odbiera dane wytworzone przez producer.js. W celu weryfikacji operacji replikacji w klastrze RabbitMQ, zachęcam do wyłączenia podczas wymiany danych przez skrypty jednego z procesów RabbitMQ, aby zobaczyć, jak będzie obsługiwany błąd i jak RabbitMQ wybierze nowego Mastera i odpowiednio przekieruje wiadomości.

rabbitmqctl -n john stop_app

wyłączenie jednej z instancji RabbitMQ nie wpływa na produkcję ani pobieranie wiadomości. Kolejki są automatycznie replikowane, a połączenie odzyskiwane bez konieczności wdrażania własnych mechanizmów.

Podsumowując, RabbitMQ to świetny system kolejkowy, który zapewnia wysoką dostępność po prawidłowej konfiguracji, która nie powoduje wielu problemów. Duża liczba bibliotek w wielu językach, np. Node.js, PHP, Java, Python, Golang, C / C++, pozwala na łatwą implementację systemu w projekcie. Polecam wszystkim zapoznanie się z dokumentacją, która bardzo jasno wyjaśnia kwestie związane z działaniem systemu i jego poprawną konfiguracją, która jest naprawdę obszerna.

cały kod jest przechowywany w repozytorium na Githubie

Podobne wyszukiwania: NodeJS rabbitmq / NodeJS queue / rabbitmq queue NodeJS