Klastry RabbitMQ i kolejki lustrzane zachowanie za kulisami

Czy ktoś może wyjaśnić, co dzieje się za kulisami w klastrze RabbitMQ z wieloma węzłami i kolejkami w sposób lustrzany podczas publikowania do węzła slave?

Z tego, co czytałem, wydaje się, że wszystkie działania inne niż publish idą tylko do mistrza, a master następnie przekazuje efekt działań do niewolników(to jest z dokumentacji). W moim rozumieniu oznacza to, że konsument zawsze będzie konsumował wiadomość z kolejki master. Również, jeśli wysyłam zapytanie do slave 'a za pochłonięcie wiadomości, Ten slave zrobi dodatkowy skok, dostając się do master' a za pobranie tej wiadomości.

Ale co się dzieje, gdy publikuję do węzła slave? Czy ten węzeł zrobi to samo, wysyłając najpierw wiadomość do mistrza?

Wydaje się, że jest tak wiele dodatkowych skoków w kontaktach z niewolnikami, więc wydaje się, że możesz mieć lepszą wydajność, jeśli znasz tylko mistrza. Ale jak sobie radzisz z porażką mistrza? Wtedy jeden z niewolników zostanie wybrany panem, więc musisz wiedzieć, gdzie się połączyć?

Pytanie o to wszystko, ponieważ używamy klastra RabbitMQ z HAProxy z przodu, więc możemy oddzielić strukturę klastra od naszych aplikacji. W ten sposób, za każdym razem, gdy węzeł zostanie wykonany, HAProxy przekieruje do żywych węzłów. Ale mamy problemy, gdy zabijamy jeden z węzłów królika. Połączenie z królikiem jest stałe, więc jeśli się nie powiedzie, musisz je odtworzyć. Ponadto musisz ponownie wysłać wiadomości w tym przypadku, w przeciwnym razie stracisz oni.

Nawet z tym wszystkim, wiadomości nadal mogą zostać utracone, ponieważ mogą być przesyłane podczas zabijania węzła (w niektórych buforach, gdzieś w sieci itp.). Musisz więc użyć transakcji lub potwierdzenia wydawcy, które gwarantują dostawę po wypełnieniu wszystkich serwerów lustrzanych wiadomością. Ale tutaj inny problem. Możesz mieć zduplikowane wiadomości, ponieważ broker mógł wysłać potwierdzenie, które nigdy nie dotarło do producenta (z powodu awarii sieci itp.). Dlatego aplikacje konsumenckie będą musiały wykonywać deduplikację lub obsługiwać przychodzące wiadomości w sposób idempotentny.

Czy można tego uniknąć? Czy muszę zdecydować, czy mogę stracić kilka wiadomości, a nie powielać niektórych wiadomości?

Author: Cosmin Vasii, 2014-11-24

1 answers

Czy ktoś może wyjaśnić, co dzieje się za kulisami w klastrze RabbitMQ z wieloma węzłami i kolejkami w lustrzany sposób podczas publikowania do węzła slave?

Ten blog przedstawia dokładnie to, co się dzieje.

Ale co się stanie, gdy opublikuję do węzła slave? Czy ten węzeł zrobi to samo, wysyłając najpierw wiadomość do mistrza?

Wiadomość zostanie przekierowana do kolejki master-czyli węzła, na którym Kolejka została utworzona.

Ale jak sobie radzisz z porażką mistrza? Wtedy jeden z niewolników zostanie wybrany mistrzem, więc musisz wiedzieć, gdzie się połączyć?

Ponownie, to jest pokryte tutaj . Zasadniczo potrzebny jest osobny serwis, który sprawdza czy węzły są żywe czy nie. RabbitMQ dostarcza do tego celu API zarządzania. Twoje aplikacje publikujące i zużywające się muszą odnosić się do tej usługi bezpośrednio lub za pośrednictwem wzajemnego przechowywanie danych w celu określenia właściwego węzła do publikowania lub korzystania z niego.

Połączenie z królikiem jest stałe, więc jeśli się nie powiedzie, musisz je odtworzyć. Ponadto musisz ponownie wysłać wiadomości w tym przypadku, w przeciwnym razie stracisz je.

Musisz subskrybować zdarzenia przerwane połączeniem, aby reagować na zerwane połączenia. Będziesz musiał zbudować pewien poziom nadmiarowości na kliencie, aby upewnić się, że wiadomości nie zostaną utracone. Proponuję, jako powyżej, że wprowadzasz usługę specjalnie zaprojektowaną do przesłuchań RabbitMQ. Klient może spróbować opublikować wiadomość do ostatniego znanego aktywnego połączenia, a jeśli to się nie powiedzie, klient może poprosić usługę monitora o aktualną listę klastra RabbitMQ. Zakładając, że jest co najmniej jeden aktywny węzeł, klient może nawiązać z nim połączenie i opublikować wiadomość pomyślnie.

Nawet z tym wszystkim, wiadomości nadal mogą zostać utracone, ponieważ może być w tranzycie, gdy zabijam węzeł

Istnieją pewne przypadki krawędzi, których nie można pokryć redundancją, podobnie jak RabbitMQ. Na przykład, gdy wiadomość wyląduje w kolejce, a zasada HA wywołuje proces w tle, aby skopiować wiadomość do węzła kopii zapasowej. Podczas tego procesu istnieje możliwość utraty wiadomości, zanim zostanie ona utrzymana w węźle kopii zapasowej. Jeśli aktywny węzeł natychmiast zawiedzie, wiadomość zostanie utracona na dobre. Nic nie można zrobić o tym. Niestety, kiedy zejdziemy do poziomu rzeczywistych bajtów podróżujących przez przewód, istnieje limit ilości zabezpieczeń, które możemy zbudować.

Dlatego aplikacje konsumenckie będą musiały wykonywać deduplikację lub obsługiwać przychodzące wiadomości w idempotentny sposób.

Możesz sobie z tym poradzić na wiele sposobów. Na przykład ustawienie message-ttl Na stosunkowo niską wartość sprawi, że zduplikowane wiadomości nie pozostaną w kolejce przez dłuższy czas czasu. Możesz również oznaczyć każdą wiadomość unikalnym odniesieniem i sprawdzić to odniesienie na poziomie konsumenta. Oczywiście wymagałoby to Przechowywania bufora przetworzonych wiadomości w celu porównania wiadomości przychodzących z nimi; chodzi o to, że jeśli wcześniej przetworzona wiadomość dotrze, jej znacznik zostanie buforowany przez konsumenta, a wiadomość może zostać zignorowana.

Jedną z rzeczy, które chciałbym podkreślić z AMQP i rozwiązań opartych na kolejkach w ogóle jest to, że Twoja infrastruktura zapewnia narzędzia, ale nie całe rozwiązanie. Musisz wypełnić te luki w oparciu o potrzeby biznesowe. Często najlepsze rozwiązanie uzyskuje się metodą prób i błędów. Mam nadzieję, że moje sugestie są przydatne. Bloguję o wielu rozwiązaniach projektowych RabbitMQ tutaj, w tym o problemach, o których wspomniałeś, tutaj jeśli jesteś zainteresowany.

 14
Author: Paul Mooney,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-25 17:43:51