Wzorzec konkurujących odbiorców

Umożliwianie wielu równoczesnym odbiorcom przetwarzania komunikatów odebranych w tym samym kanale obsługi komunikatów. W przypadku wielu równoczesnych użytkowników system może przetwarzać wiele komunikatów w tym samym czasie, aby zoptymalizować przepływność, zwiększyć skalowalność i dostępność oraz zrównoważyć obciążenie.

Kontekst i problem

Aplikacja w chmurze często obsługuje dużą liczbę żądań. Zamiast synchronicznie przetwarzać każde żądanie, aplikacja może przekazywać żądania za pośrednictwem systemu obsługi komunikatów do usługi konsumenta, która obsługuje je asynchronicznie. Ta strategia pomaga zapobiec blokowaniu logiki biznesowej aplikacji przez przetwarzanie żądań.

Liczba żądań może się znacznie różnić w czasie. Nagły wzrost aktywności użytkowników lub zagregowanych żądań od wielu klientów może spowodować nieprzewidywalne obciążenie. W godzinach szczytu system może wymagać przetwarzania wielu setek żądań na sekundę. Czasami liczba może być mała. Ponadto praca wymagana do obsługi tych żądań może się znacznie różnić. Jeśli używasz pojedynczego wystąpienia usługi konsumenckiej, żądania mogą nadmiernie obciążyć to wystąpienie. Lub napływ komunikatów aplikacji może przeciążyć system obsługi komunikatów.

Aby obsłużyć to zmienne obciążenie, system może uruchamiać wiele instancji usług klienckich. Jednak system musi koordynować tych odbiorców, aby upewnić się, że każdy komunikat jest dostarczany tylko do jednego konsumenta. System musi również zbalansować obciążenie między konsumentami, aby zapobiec powstawaniu wąskiego gardła w jednej instancji.

Rozwiązanie

Aby zrealizować kanał komunikacyjny między aplikacją a instancjami usługi konsumenckiej, należy użyć kolejki komunikatów. Aplikacja publikuje żądania jako komunikaty do kolejki, a wystąpienia usług konsumenckich odbierają i przetwarzają komunikaty z kolejki. Takie podejście umożliwia tej samej puli instancji usług klienckich obsługę komunikatów z dowolnego wystąpienia aplikacji. Na poniższym diagramie pokazano, jak kolejka komunikatów dystrybuuje pracę do wystąpień usługi.

Diagram przedstawiający, jak kolejka komunikatów rozdziela zadania pomiędzy wystąpienia usługi.

Uwaga / Notatka

Wielu użytkowników odbiera te komunikaty, ale wzorzec konkurujących odbiorców różni się od wzorcaPublisher-Subscriber. W wzorcu Konkurujących Konsumentów jeden konsument otrzymuje każdą wiadomość do przetworzenia. We wzorcu Publisher-Subscriber wszyscy użytkownicy otrzymują każdy komunikat.

To rozwiązanie ma następujące korzyści:

  • Zapewnia system równoważenia obciążenia, który może obsługiwać szerokie różnice w natężeniu żądań z instancji aplikacji. Kolejka działa jako bufor między wystąpieniami aplikacji i wystąpieniami usługi konsumenckiej. Ten bufor może zminimalizować wpływ na dostępność i czas odpowiedzi zarówno dla aplikacji, jak i wystąpień usługi. Aby uzyskać więcej informacji, zobacz Wzorzec bilansowania obciążenia opartego na kolejce. Komunikat, który wymaga długotrwałego przetwarzania, nie uniemożliwia innym wystąpieniom usług konsumenckich jednoczesnego przetwarzania innych komunikatów.

  • Zwiększa niezawodność. Jeśli producent komunikuje się bezpośrednio z konsumentem zamiast używać tego wzorca i nie monitoruje konsumenta, ma duże prawdopodobieństwo utraty komunikatów lub nie przetworzenia ich, gdy konsument ulegnie awarii. W tym wzorcu system nie wysyła komunikatów do określonego wystąpienia usługi. Instancja usługi, która zakończyła się niepowodzeniem, nie blokuje producenta, a każda działająca instancja usługi może przetwarzać komunikaty.

  • Nie wymaga to skomplikowanej koordynacji między konsumentami ani między instancjami producenta i konsumenta. Kolejka komunikatów gwarantuje, że każdy komunikat zostanie dostarczony co najmniej raz.

  • Skaluje. Podczas stosowania skalowania automatycznego system może dynamicznie zwiększać lub zmniejszać liczbę wystąpień usług konsumenckich w miarę wahań liczby komunikatów.

  • Może to zwiększyć odporność, jeśli kolejka komunikatów udostępnia transakcyjne operacje odczytu. Jeśli instancja usługi konsumenckiej odczytuje i przetwarza komunikat w ramach operacji transakcyjnej i kończy się niepowodzeniem, ten wzorzec może zapewnić, że komunikat zostanie zwrócony do kolejki, aby inne instancje usługi konsumenckiej mogły go przetworzyć. Aby ograniczyć ryzyko ciągłych błędów komunikatów, zalecamy użycie kolejek utraconych komunikatów.

Problemy i zagadnienia

Podczas podejmowania decyzji o zaimplementowaniu tego wzorca należy wziąć pod uwagę następujące kwestie:

  • Kolejność komunikatów: Kolejność, w jakiej instancje usług konsumenckich odbierają komunikaty, nie jest gwarantowana i nie odzwierciedla kolejności, w jakiej komunikaty zostały utworzone. Zaprojektuj system tak, aby przetwarzał komunikaty idempotentnie. Ten projekt pomaga wyeliminować zależności kolejności przetwarzania.

    Usługa Azure Service Bus umożliwia zaimplementowanie gwarantowanej kolejności typu pierwszy-wszedł, pierwszy-wyszedł dla komunikatów oraz innych wzorców przy użyciu sesji komunikatów.

  • Wymagania dotyczące odporności usługi: Jeśli system wykryje i ponownie uruchomi wystąpienia usługi, które zakończyły się niepowodzeniem, może być konieczne zaimplementowanie operacji wykonywanych przez te wystąpienia usług jako idempotentne, aby zminimalizować skutki pobierania i przetwarzania pojedynczego komunikatu więcej niż raz.

  • Wykrywanie komunikatów zatrutych: Źle sformułowany komunikat lub zadanie wymagające dostępu do niedostępnych zasobów może spowodować niepowodzenie wystąpienia usługi. System powinien uniemożliwić powrót tych komunikatów do kolejki na czas nieokreślony, a zamiast tego przechwytywać i przechowywać ich szczegóły w innym miejscu na potrzeby analizy, jeśli to konieczne. Usługa Service Bus może automatycznie wysyłać komunikaty do kolejki utraconych komunikatów po przekroczeniu skonfigurowanego MaxDeliveryCount progu przez liczbę dostaw.

  • Obsługa wyników: Wystąpienie usługi, które obsługuje komunikat, jest w pełni oddzielone od logiki aplikacji, która generuje komunikat, więc mogą nie być w stanie komunikować się bezpośrednio. Jeśli wystąpienie usługi generuje wyniki, które muszą wrócić do logiki aplikacji, zapisz te informacje w lokalizacji, do której mogą uzyskać dostęp oba składniki. Aby zapobiec pobieraniu niekompletnych danych przez logikę aplikacji, system musi wskazać, kiedy przetwarzanie zakończy się. Proces roboczy może przekazywać wyniki z powrotem do logiki aplikacji za pośrednictwem dedykowanej kolejki komunikatów z odpowiedziami. Logika aplikacji musi mieć możliwość skorelowania tych wyników z oryginalnym komunikatem.

  • Skalowanie systemu obsługi komunikatów: W rozwiązaniu na dużą skalę, wysoki wolumin komunikatów może przeciążyć pojedynczą kolejkę komunikatów i przekształcić ją w wąskie gardło systemu. W takiej sytuacji należy rozważyć partycjonowanie systemu obsługi komunikatów w celu wysyłania komunikatów od określonych producentów do określonej kolejki lub równoważenia obciążenia w celu dystrybucji komunikatów w wielu kolejkach komunikatów.

  • Niezawodność systemu obsługi komunikatów: Użyj niezawodnego systemu obsługi komunikatów, aby zagwarantować, że komunikaty nie zostaną utracone po zapisaniu ich w kolejce przez aplikację. Ta funkcja jest niezbędna do zapewnienia, że wszystkie komunikaty są dostarczane co najmniej raz.

Kiedy należy używać tego wzorca

Użyj tego wzorca, gdy:

  • Obciążenie aplikacji jest podzielone na zadania, które mogą być uruchamiane asynchronicznie.

  • Zadania są niezależne i mogą być uruchamiane równolegle.

  • Wolumin roboczy jest wysoce zmienny i wymaga skalowalnego rozwiązania.

  • Rozwiązanie musi zapewnić wysoką dostępność i zachować odporność, gdy przetwarzanie zadań zakończy się niepowodzeniem.

Ten wzorzec może nie być odpowiedni w następujących przypadkach:

  • Nie można łatwo oddzielić obciążenia aplikacji do odrębnych zadań lub istnieje wysoki stopień zależności między zadaniami.

  • Zadania muszą być uruchamiane synchronicznie, a logika aplikacji musi czekać na ukończenie każdego zadania, zanim będzie kontynuowane.

  • Zadania muszą być uruchamiane w określonej sekwencji.

Uwaga / Notatka

Niektóre systemy obsługi komunikatów obsługują sesje, które pozwalają producentowi grupować komunikaty razem i zapewnić, że ten sam użytkownik obsługuje wszystkie komunikaty w grupie. Tego mechanizmu można używać z priorytetowymi komunikatami, gdy obsługiwane jest wymuszanie porządkowania komunikatów i dostarczanie komunikatów w sekwencji od producenta do pojedynczego odbiorcy.

Projektowanie obciążenia pracy

Oceń, jak używać wzorca konkurujących użytkowników w projekcie aplikacji, aby sprostać celom i zasadom opisanym w filarach platformy Azure Well-Architected Framework. Poniższa tabela zawiera wskazówki dotyczące tego, jak ten wzorzec obsługuje cele poszczególnych filarów.

Filar Jak ten wzorzec obsługuje cele filaru
Decyzje projektowe dotyczące niezawodności pomagają obciążeniom stały się odporne na awarię i zapewniają, że zostanie ono przywrócone do w pełni funkcjonalnego stanu po wystąpieniu awarii. Ten schemat tworzy redundancję w przetwarzaniu kolejek, traktując konsumentów jako repliki, więc awaria instancji nie uniemożliwia innym konsumentom przetwarzania komunikatów w kolejce.

- RE:05 Redundancja
- Zadania w tle
Optymalizacja kosztów koncentruje się na utrzymaniu i poprawiezwrotu obciążenia z inwestycji. Ten wzorzec może pomóc w optymalizacji kosztów, ponieważ skaluje się na podstawie głębokości kolejki i może być skalowany w dół do zera, gdy kolejka jest pusta. Może również zoptymalizować koszty, ponieważ można ograniczyć maksymalną liczbę współbieżnych wystąpień konsumentów.

- CO:05 Optymalizacja szybkości
- KOSZT SKŁADNIKA CO:07
Efektywność wydajności pomaga wydajnie sprostać wymaganiom dzięki optymalizacjom skalowania, danych i kodu. Ten wzorzec dystrybuuje obciążenie między węzłami konsumenckimi, aby zwiększyć efektywność wykorzystania zasobów, a dynamiczne skalowanie na podstawie głębokości kolejki minimalizuje nadmierną rezerwację zasobów.

- PE:05 Skalowanie i partycjonowanie
- PE:07 Kod i infrastruktura

Jeśli ten wzorzec wprowadza kompromisy w ramach filaru, rozważ je przed celami innych filarów.

Przykład

Platforma Azure udostępnia kolejki usługi Service Bus i wyzwalacze kolejek usługi Azure Functions, które razem bezpośrednio implementują ten wzorzec projektowania chmury. Funkcje integrują się z usługą Service Bus za pośrednictwem wyzwalaczy i powiązań. Ta integracja umożliwia tworzenie funkcji korzystających z komunikatów kolejek od wydawców. Aplikacje publikujące komunikaty w kolejce, a konsumenci zaimplementowani jako funkcje mogą pobierać i obsługiwać te komunikaty.

W celu zapewnienia niezawodności kolejka usługi Service Bus umożliwia użytkownikowi korzystanie z trybu PeekLock podczas pobierania komunikatu z kolejki. Ten tryb przechowuje komunikat, ale ukrywa go przed innymi użytkownikami. Środowisko uruchomieniowe usługi Functions odbiera komunikat w trybie PeekLock. Jeśli funkcja zakończy się pomyślnie, środowisko uruchomieniowe wywołuje Complete na komunikacie. Jeśli funkcja zakończy się niepowodzeniem, środowisko uruchomieniowe może wywołać Abandon i ponownie wyświetlić komunikat, aby inny odbiorca mógł go pobrać. Jeśli funkcja działa dłużej niż limit czasu PeekLock, środowisko uruchomieniowe automatycznie odnawia blokadę tak długo, jak działa funkcja.

Diagram wykorzystujący Azure Service Bus do rozdzielania zadań do Azure Functions.

Funkcja automatycznie skaluje liczbę wystąpień konsumentów na podstawie głębokości kolejki i ruchu. To skalowanie umożliwia rozwiązaniu obsługę nagłych wzrostów obciążenia, minimalizując koszty w okresach niskiej aktywności. Jeśli usługa Functions tworzy wiele wystąpień, konkurują niezależnie ściągając i przetwarzając komunikaty. Aby uzyskać więcej informacji, zobacz Kolejki, tematy i subskrypcje usługi Service Bus oraz wyzwalacz usługi Service Bus dla usługi Functions.

Aby uzyskać więcej informacji na temat używania biblioteki klienta usługi Service Bus dla platformy .NET do wysyłania komunikatów do kolejki usługi Service Bus, zobacz opublikowane przykłady.

Następne kroki

  • Wybierz usługę obsługi komunikatów na platformie Azure: dowiedz się, jak różne usługi obsługi komunikatów platformy Azure, takie jak Service Bus, kolejki usługi Azure Storage, usługi Azure Event Hubs i usługa Azure Event Grid obsługują asynchroniczne wzorce komunikacji oraz jak wybrać odpowiedni model obsługi usług i komunikatów dla danego scenariusza.

  • Najlepsze praktyki skalowania automatycznego: dowiedz się, jak projektować rozwiązania umożliwiające skalowanie w poziomie instancji konsumenckich w oparciu o obciążenie, takie jak długość kolejki lub przepustowość komunikatów, aby móc obsługiwać szczytowe obciążenia i kontrolować koszty w okresach niskiej aktywności.

  • Wzorzec konsolidacji zasobów obliczeniowych: możesz skonsolidować wiele wystąpień usługi konsumenckiej w jeden proces, aby zmniejszyć koszty i koszty związane z zarządzaniem. Wzorzec konsolidacji zasobów obliczeniowych opisuje korzyści i kompromisy w tym podejściu.

  • Wzorzec bilansowania obciążenia opartego na kolejce: kolejka komunikatów może zwiększyć odporność systemu. Odporność pozwala wystąpieniom usługi na obsługę szeroko zróżnicowanych wolumenów żądań z wystąpień aplikacji. Kolejka komunikatów działa jako bufor, który wyrównuje obciążenie. Wzorzec wyrównywania obciążeń przy użyciu kolejki opisuje ten scenariusz bardziej szczegółowo.