Why Rabbit? Czym jest MQ? Jak może on ulepszyć nasze aplikacje? Dlaczego miałbym chcieć dowiedzieć się o nim więcej? – To są pytania, które zadawałem sobie, gdy po raz pierwszy zostałem wprowadzony do RabbitMQ. Jestem Gabor, a obecnie jestem inżynierem i konsultantem RabbitMQ. W czasie mojej pracy z RabbitMQ nauczyłem się, że nawet doświadczeni klienci zadają te pytania.
TL;DR >Sprawdź naszą stronę produktu RabbitMQ, aby poznać przypadki użycia, cechy oraz skontaktować się z naszymi konsultantami-ekspertami.
Jaki problem rozwiązuje RabbitMQ?
Zanim zagłębimy się w to, czym jest RabbitMQ i jak go używać, warto dowiedzieć się więcej o samej domenie problemu. Komunikacja pomiędzy różnymi usługami (a.k.a. komputerami) jest odwiecznym problemem.
Z jednej strony, istnieją różne protokoły definiujące środki transportu i właściwości komunikacji. Niektóre przykłady takich protokołów obejmują SMTP, FTP, HTTP lub WebSockets (aby wymienić tylko kilka), które są oparte na TCP/UDP. Zajmują się one formatowaniem, niezawodnością i znalezieniem właściwego odbiorcy wiadomości.
Z drugiej strony, możemy zbadać komunikację z perspektywy wiadomości. Istnieje ona w jednym systemie, następnie jest transportowana do innego, ulega transformacji, czyli ma swój cykl życia. W trakcie przemieszczania się z jednego systemu do drugiego, powinniśmy być świadomi, gdzie znajduje się wiadomość i kto jest jej właścicielem w danym momencie.
Protokoły komunikacyjne wspomniane powyżej mogą zapewnić, że własność (i „fizyczna” lokalizacja) wiadomości jest przekazywana z jednego systemu do drugiego (chociaż wykonanie tej transakcji może zająć trochę czasu). Możemy uznać transfer za transakcję pomiędzy dwoma stronami, podczas gdy obie są obecne. W większości przypadków ta aktywna wymiana jest pożądana, np. zapytanie o status usługi i oczekiwanie terminowej i dokładnej odpowiedzi. Przykładem ze świata fizycznego byłoby dzwonienie do kogoś przez telefon:
1) rozpoczynamy połączenie,
2) czekamy na odpowiedź drugiej strony,
3) prowadzimy miłą dyskusję,
4) odkładamy słuchawkę.
Ale są też inne czasy, kiedy nie potrzebujemy odpowiedzi, potrzebujemy tylko, aby odbiorca przejął własność wiadomości i wykonał swoją pracę. W tym przypadku potrzebujemy agenta pośredniczącego, innego systemu, który przejmie własność wiadomości (tymczasowo) i upewni się, że wiadomość dotrze do celu. Aby posunąć się dalej w przykładzie z telefonem, druga strona nie jest dostępna w tej chwili, więc zostawiamy wiadomość głosową. Usługa poczty głosowej powiadomi o tym odbiorcę.
To asynchroniczne (opóźnione) dostarczanie wiadomości jest tym, co zapewnia RabbitMQ. Oczywiście, może on zrobić więcej niż zwykła automatyczna sekretarka, więc zbadajmy niektóre z opcji, które zapewnia poniżej
(Jeśli jesteś zainteresowany poznaniem historii RabbitMQ, polecam pierwszy rozdział „RabbitMQ in Action” autorstwa Alvaro Videla i Jason Williams. Znajdziesz w nim odpowiedź na pytanie, dlaczego jego nazwa pochodzi od Królików).
RabbitMQ jest darmowym, open-source’owym i rozszerzalnym rozwiązaniem do kolejkowania wiadomości. Jest to broker wiadomości, który rozumie AMQP (Advanced Message Queuing Protocol), ale może być również używany z innymi popularnymi rozwiązaniami do przesyłania wiadomości, takimi jak MQTT. Jest wysoce dostępny, odporny na błędy i skalowalny. Jest on zaimplementowany w Erlang OTP, technologii dostosowanej do budowania stabych, niezawodnych, odpornych na błędy i wysoce skalowalnych systemów, które posiadają natywne możliwości obsługi bardzo dużej liczby współbieżnych operacji, jak ma to miejsce w przypadku RabbitMQ i innych systemów takich jak WhatsApp, MongooseIM, aby wymienić tylko kilka.
Na bardzo wysokim poziomie, jest to warstwa oprogramowania pośredniego, która umożliwia różnym usługom w aplikacji komunikować się ze sobą bez obawy o utratę wiadomości, zapewniając jednocześnie różne wymagania jakości usług (QoS). Umożliwia również drobnoziarnisty i wydajny routing komunikatów, umożliwiając rozległe oddzielenie aplikacji.
Przypadki użycia
Aby zaprezentować wszechstronność RabbitMQ, użyjemy trzech studiów przypadku, które pokazują, jak RabbitMQ dobrze nadaje się jako usługa zarządzana typu black-box, jako taka, która ściśle integruje się z aplikacją, umożliwiając dobrze funkcjonującą architekturę mikroserwisów, lub jako brama do innych starszych projektów.
RabbitMQ jako ogólna magistrala komunikacyjna
Gdy system monolityczny jest rozbijany na oddzielne podsystemy, jednym z największych problemów, które trzeba rozwiązać, jest to, jakiej technologii komunikacyjnej użyć. Rozwiązania takie jak Mulesoft, czy MassTransit mogą „okablować” usługi poprzez zadeklarowanie słuchaczy i nadawców HTTP. Tego typu rozwiązanie traktuje RabbitMQ jako czarną skrzynkę, ale wciąż jest w stanie wykorzystać możliwości RabbitMQ. Jako przykład komunikacji bezpośredniej, użyjmy HTTP do „połączenia” poszczególnych usług. Chociaż jest to dobrze wspierany i solidny wybór, ma on pewne wady:
1) Nie jest rozwiązana kwestia wykrywania usług. Możliwym rozwiązaniem jest użycie DNS. W miarę jak system się skaluje i rośnie, rośnie też złożoność wyszukiwania i równoważenia tego obciążenia. RabbitMQ może złagodzić zwiększoną złożoność rozwiązania.
2) Komunikacja jest efemeryczna. Komunikaty są podatne na porzucanie lub duplikowanie w warstwie sieciowej. Jeśli usługa jest chwilowo niedostępna, dostawa nie powiedzie się.
RabbitMQ może pomóc w obu przypadkach, wykorzystując kolejki komunikatów jako środek transportu. Usługi mogą publikować i konsumować wiadomości, co pozwala oddzielić dostarczanie wiadomości end-to-end od dostępności usługi docelowej. Jeśli usługa konsumująca jest tymczasowo niedostępna, w przeciwieństwie do HTTP, wiadomość jest bezpiecznie buforowana i przechowywana w RabbitMQ, a następnie dostarczana, gdy usługa powróci do sieci.
Odkrywalność jest również uproszczona. Wszystko, co musimy wiedzieć, to gdzie jest RabbitMQ i jaka jest nazwa kolejki. Choć wydaje się, że jest to ponowne rozwiązanie problemu, jest to rozwiązanie skalowalne. Nazwa kolejki działa jak adres usługi. Konsumowanie wiadomości z kolejek przez poszczególne usługi daje możliwość skalowalności, tzn. każda kolejka może obsługiwać wielu konsumentów i równoważyć obciążenie. Nie ma potrzeby zmieniać konfiguracji kolejek już wbudowanych w usługi.
Ta umiarkowanie statyczna konfiguracja kolejek popycha RabbitMQ do warstwy middleware, gdzie solidny projekt może zagwarantować stabilną jakość usług w długim okresie.
RabbitMQ jako zaawansowana warstwa routingu dla mikroserwisów
Na drugim końcu spektrum znajduje się architektura, która jest bardziej płynna i dostosowuje się do ciągle zmieniających się potrzeb wielu mikroserwisów. To, co sprawia, że RabbitMQ błyszczy w tym środowisku, to bardzo potężne możliwości routingu, które zapewnia.
Logika routingu jest zaimplementowana w różnych (tak zwanych) typach wymiany, które mogą być dynamicznie tworzone przez aplikację, gdy są potrzebne. Usługi docelowe tworzą kolejki, z których chcą korzystać, a następnie wiążą je z wymianami poprzez określenie wzorca dla kluczy, których wydawcy mogą używać podczas publikowania wiadomości. (Pomyśl o tych kluczach jako o metadanych, których giełdy mogą używać do routingu i dostarczania wiadomości do jednej lub więcej kolejek.)
Logika routingu jest zaimplementowana w różnych (tak zwanych) typach wymiany, które mogą być dynamicznie tworzone przez aplikację w razie potrzeby. Usługi docelowe tworzą kolejki, z których chcą korzystać, a następnie wiążą je z wymianami poprzez określenie wzorca dla kluczy, których wydawcy mogą używać podczas publikowania wiadomości. (Pomyśl o tych kluczach jako o metadanych, które giełdy mogą wykorzystać do kierowania i dostarczania wiadomości do jednej lub więcej kolejek.)
RabbitMQ posiada cztery użyteczne typy wymiany, które pokrywają większość przypadków użycia wiadomości:
1) Wymiana bezpośrednia. Dostarczy ona przychodzący komunikat do dowolnej kolejki, której klucz wiązania dokładnie odpowiada kluczowi routingu komunikatu. Jeśli powiążesz kolejki z nazwą kolejki jako kluczami routingu, wtedy możesz myśleć o tym jako o dostarczaniu wiadomości jeden do jednego. Łatwo jest dostarczyć ten sam komunikat do wielu kolejek poprzez użycie kluczy wiążących dla wielu kolejek.
2) Topic exchange. W ten sposób przychodzący komunikat zostanie dostarczony do dowolnej kolejki, której klucz wiążący typu wild-card pasuje do klucza routingu opublikowanego komunikatu. Klucze wiążące mogą zawierać kryteria dopasowania do złożonego klucza routingu. (np. klucz wiążący logs.*.error
będzie pasował do kluczy routingu logs.accounting.error
i logs.ui.error
). Dzięki temu możemy pisać proste usługi, w których logika jest dobrze opanowana, a wiadomość dotrze do właściwych usług dzięki „magii” RabbitMQ.
3) Wymiana Fanout. Niektóre wiadomości muszą być dostarczone do wszystkich kolejek, w tym przypadku można użyć fanout exchange zamiast pisania rozbudowanej logiki multicastu w aplikacji. W przypadku wymiany fanout RabbitMQ, każda usługa wiąże odpowiednią kolejkę z wymianą bez konieczności podawania klucza wiążącego, a wszystko to dzieje się automatycznie. Jeśli klucz wiążący jest określony, wymiana fanout po prostu go zignoruje i nadal będzie kierować/rozsyłać wiadomości do wszystkich kolejek do niej przypisanych.
4) Wymiana nagłówków. Ta wymiana wykorzystuje strukturę wiadomości AMQP i jest zdolna do kompleksowego routingu w oparciu o nagłówki (w tym niestandardowe) wiadomości AMQP. Nagłówki są metadanymi dołączanymi do każdej wiadomości wysyłanej przez AMQP.
Oprócz wymiany, RabbitMQ posiada inne użyteczne cechy, które umożliwiają implementację bardzo złożonej logiki przesyłania wiadomości. Niektóre z najważniejszych cech obejmują:
1) Niestandardowe wtyczki. RabbitMQ jest rozszerzalny poprzez umożliwienie jego użytkownikom dodawania wtyczek. Prawie każdy aspekt RabbitMQ jest konfigurowalny, włączając w to zarządzanie, uwierzytelnianie i autoryzację, rozwiązania do tworzenia kopii zapasowych oraz klastrowanie.
2) Klastrowanie. Gdy pojedynczy serwer RabbitMQ nie wystarcza, wiele brokerów RabbitMQ może być połączonych w celu współpracy i skalowania systemu. Może to umożliwić RabbitMQ przetworzenie większej ilości wiadomości lub zwiększyć odporność na błędy.
3) Dostrajanie jakości usług (Quality of Service). Dostarczanie wiadomości wrażliwych na czas może być wspomagane przez dołączenie wartości TTL (Time-to-Live) zarówno do wiadomości jak i do kolejki. Wiadomości, których czas upłynął, mogą być automatycznie dostarczane do kolejki Dead-letter. Połączenie zwykłej logiki routingu z tymi dodatkowymi funkcjami może prowadzić do bardzo zaawansowanej logiki routingu. Inną użyteczną cechą jest użycie kolejek priorytetowych, gdzie wydawca może przypisać poziom priorytetu do każdej wiadomości. Możliwe jest również ograniczenie liczby niepotwierdzonych wiadomości, co pozwala na dostrojenie wydajności usług konsumujących, w tym przypadku RabbitMQ stosuje mechanizm back-pressure.
RabbitMQ zintegrowany ze starszymi systemami
W poprzednim przypadku użycia wspomniałem o możliwości wykorzystania wtyczek do rozszerzenia funkcjonalności RabbitMQ. Ta potężna cecha pozwala RabbitMQ działać jako warstwa pośrednicząca pomiędzy natywnymi usługami RabbitMQ (obsługującymi AMQP) a innymi starszymi aplikacjami. Niektóre godne uwagi przykłady obejmują:
1) Używanie RabbitMQ jako brokera MQTT poprzez proste włączenie wtyczki. To otwiera krajobraz dla wielu technologii IoT.
2) Wtyczka JMS (Java Message Service), która pozwala RabbitMQ komunikować się z dowolnym rozwiązaniem komunikacyjnym obsługującym JMS.
3) Jeśli Twoja aplikacja używa własnościowego protokołu do komunikacji, możliwe jest stworzenie niestandardowej wtyczki, aby połączyć się z takimi usługami.
Podsumowanie
Jak pokazują powyższe przykłady, nie ma prawie niczego, z czym RabbitMQ nie mógłby się komunikować. Ale jak ze wszystkim w życiu, ma to swoją cenę. Chociaż konfiguracja RabbitMQ jest w większości przypadków prosta, czasami sama liczba funkcji może być przytłaczająca. Jeśli masz jakiekolwiek problemy z projektowaniem, wdrażaniem lub wspieraniem brokerów RabbitMQ, skontaktuj się z naszym zespołem ekspertów tutaj. Jeśli chcesz rozpocząć swoją karierę w jednej z najbardziej poszukiwanych technologii, zapisz się na nasze 3-dniowe szkolenie RabbitMQ.
Debugowanie RabbitMQ
Chcesz intuicyjnego systemu, który sprawi, że monitorowanie i utrzymanie Twojego RabbitMQ będzie łatwe? Pobierz darmową 45-dniową wersję próbną WombatOAM już teraz.
Nasza strona o możliwościach RabbitMQ