Wzorzec kolejki priorytetowej

Azure Service Bus

Wzorzec kolejki priorytetu umożliwia obciążeniu szybsze przetwarzanie zadań o wysokim priorytcie niż zadania o niższym priorytcie. Ten wzorzec używa komunikatów wysyłanych do co najmniej jednej kolejki i jest przydatny w aplikacjach, które oferują różne gwarancje dotyczące poziomu usług dla poszczególnych klientów.

Kontekst i problem

Obciążenia często muszą zarządzać zadaniami i przetwarzać je z różnym poziomem ważności i pilności. Niektóre zadania wymagają natychmiastowej uwagi, podczas gdy inne mogą czekać. Brak rozwiązywania problemów z zadaniami o wysokim priorytcie może mieć wpływ na środowisko użytkownika i naruszenie umów dotyczących poziomu usług (SLA).

Aby efektywnie obsługiwać zadania na podstawie ich priorytetu, obciążenia muszą mieć mechanizm określania priorytetów i wykonywania odpowiednio zadań. Zazwyczaj obciążenia przetwarzają zadania w kolejności, w której docierają, przy użyciu struktury kolejki pierwszy na wyjeździe (FIFO). Takie podejście nie uwzględnia różnego znaczenia zadań.

Rozwiązanie

Kolejki priorytetowe umożliwiają obciążenia przetwarzania zadań na podstawie ich priorytetu, a nie kolejności przylotu. Aplikacja wysyłająca komunikat do kolejki przypisuje priorytet komunikatowi, a konsumenci przetwarzają komunikaty według priorytetu. Użyj wzorca kolejki priorytetu, jeśli masz następujące wymagania:

  • Obsługa zadań o różnej pilności i ważności. Masz zadania z różnymi poziomami pilności i ważności i musisz upewnić się, że przetwarzasz bardziej krytyczne zadania przed mniej krytycznymi zadaniami.

  • Obsługa różnych umów dotyczących poziomu usług. Oferujesz różne gwarancje dotyczące poziomu usług dla klientów i musisz zapewnić klientom o wysokim priorytcie lepszą wydajność i dostępność.

  • Obsługa różnych potrzeb związanych z zarządzaniem obciążeniami. Masz obciążenie, które musi natychmiast rozwiązywać niektóre zadania, a mniej pilne zadania mogą czekać.

Istnieją dwa główne podejścia do implementowania wzorca kolejki priorytetu:

  • Pojedyncza kolejka: wszystkie komunikaty są wysyłane do jednej kolejki i każdy komunikat ma przypisany priorytet.

  • Wiele kolejek: oddzielne kolejki są używane dla każdego priorytetu komunikatu.

Pojedyncza kolejka

W przypadku pojedynczej kolejki aplikacja (producent) przypisuje priorytet do każdego komunikatu i wysyła komunikat do kolejki. Kolejka porządkuje komunikaty według priorytetu, zapewniając, że użytkownicy przetwarzają komunikaty o wyższym priorytcie przed komunikatami o niższym priorytcie.

Diagram ilustrujący mechanizm kolejkowania obsługujący priorytetyzację komunikatów.
Rysunek 1. Architektura pojedynczej kolejki i pojedynczej puli odbiorców

Wiele kolejek

Wiele kolejek umożliwia oddzielenie komunikatu według priorytetu. Aplikacja przypisuje priorytet każdemu komunikatowi i kieruje komunikat do kolejki odpowiadającej jej priorytetowi. Konsumenci przetwarzają komunikaty. Rozwiązanie z wieloma kolejkami używa pojedynczej puli odbiorców lub wielu pul odbiorców.

Wiele pul odbiorców

W przypadku wielu pul odbiorców każda kolejka ma dedykowane zasoby konsumentów. Kolejki o wyższym priorytcie powinny używać większej liczby odbiorców lub wyższych warstw wydajności do szybszego przetwarzania komunikatów niż kolejki o niższym priorytcie.

Użyj wielu pul odbiorców, jeśli masz:

  • Ścisłe wymagania dotyczące wydajności: wiele pul odbiorców jest niezbędnych, gdy różne priorytety zadań mają ścisłe wymagania dotyczące wydajności, które muszą być spełnione niezależnie.
  • Wymagania dotyczące wysokiej niezawodności: wiele pul odbiorców jest wymaganych w przypadku aplikacji, w których niezawodność i izolacja błędów mają krytyczne znaczenie. Problemy w jednej kolejce nie mogą mieć wpływu na inne kolejki.
  • Złożone aplikacje: korzystne dla złożonych aplikacji z zadaniami wymagającymi różnych cech przetwarzania i gwarancji wydajności dla różnych zadań.

Diagram ilustrujący użycie oddzielnych kolejek komunikatów dla każdego priorytetu.
Rysunek 2. Architektura wielu kolejek i wielu pul odbiorców.

Pojedyncza pula odbiorców

W przypadku pojedynczej puli odbiorców wszystkie kolejki współdzielą jedną pulę odbiorców. Konsumenci przetwarzają komunikaty z kolejki o najwyższym priorycie priorytetu i przetwarzają komunikaty tylko z kolejek o niższym priorytcie, gdy nie ma komunikatów o wysokim priorytcie. W związku z tym pojedyncza pula odbiorców zawsze przetwarza komunikaty o wyższym priorytcie przed niższym priorytetem. Ta konfiguracja może prowadzić do ciągłego opóźnienia komunikatów o niższym priorytcie i potencjalnie nigdy nie są przetwarzane.

Użyj pojedynczej puli odbiorców dla:

  • Proste zarządzanie: pojedyncza pula odbiorców jest odpowiednia dla aplikacji, w której łatwość instalacji i konserwacji jest priorytetem. Zmniejsza złożoność konfiguracji i monitorowania.
  • Ujednolicone potrzeby przetwarzania: pojedyncza pula odbiorców jest przydatna, gdy dokładny charakter zadań przychodzących jest podobny.

Diagram ilustrujący użycie oddzielnych kolejek komunikatów dla każdego priorytetu.
Rysunek 3. Architektura wielu kolejek i pojedynczej puli odbiorców.

Zalecenia dotyczące wzorca kolejki priorytetowej

Podczas podejmowania decyzji o zaimplementowaniu wzorca kolejki priorytetu należy wziąć pod uwagę następujące zalecenia:

Zalecenia ogólne

  • Jasno zdefiniuj priorytety. Ustanów odrębne i jasne poziomy priorytetów odpowiednie dla rozwiązania. Na przykład komunikat o wysokim priorytcie może wymagać przetworzenia w ciągu 10 sekund. Zidentyfikuj wymagania dotyczące obsługi elementów o wysokim priorytcie i odpowiednio przydziel niezbędne zasoby.

  • Dynamiczne dostosowywanie pul odbiorców. Skaluj rozmiar pul odbiorców na podstawie długości kolejki, która jest obsługiwana.

  • Określanie priorytetów poziomów usług. Zaimplementuj kolejki priorytetów, aby spełnić potrzeby biznesowe, które wymagają priorytetowej dostępności lub wydajności. Na przykład różne grupy klientów mogą otrzymywać różne poziomy usług, dzięki czemu klienci o wysokim priorycie mają lepszą wydajność i dostępność.

  • Upewnij się, że przetwarzanie o niskim priorytcie. W kolejkach, które obsługują priorytetyzację komunikatów, dynamicznie zwiększają priorytet przestarzałych komunikatów, jeśli system umożliwia mu zapewnienie, że komunikaty o niskim priorytcie zostaną ostatecznie przetworzone.

  • Rozważ koszty kolejki. Należy pamiętać o kosztach finansowych i przetwarzania związanych z kolejkami sprawdzania. Niektóre usługi kolejek pobierają opłaty za publikowanie, pobieranie i wykonywanie zapytań dotyczących komunikatów, co może wzrosnąć wraz z liczbą kolejek.

Zalecenia dotyczące wielu kolejek

  • Monitorowanie szybkości przetwarzania. Aby upewnić się, że komunikaty są przetwarzane zgodnie z oczekiwanymi szybkościami, stale monitoruj szybkość przetwarzania kolejek o wysokim i niskim priorytcie.

  • Minimalizuj koszty. Natychmiast przetwarzaj zadania krytyczne dla dostępnych użytkowników. Zaplanuj mniej krytyczne zadania w tle w krótszym czasie pracy.

Zalecenia dotyczące pojedynczej puli odbiorców

  • Zaimplementuj wywłaszczanie i zawieszenie. Zdecyduj, czy wszystkie elementy o wysokim priorytcie muszą być przetwarzane przed wszystkimi elementami o niższym priorytcie. Użyj algorytmu, który zapewnia, że kolejki o wysokim priorytcie są zawsze obsługiwane przed kolejkami o niższym priorytcie podczas korzystania z pojedynczej puli odbiorców dla wielu kolejek.

  • Optymalizowanie kosztów. Zoptymalizuj koszty operacyjne, skalując liczbę użytkowników w przypadku korzystania z podejścia z jedną kolejką. Komunikaty o wysokim priorytcie najpierw przetwarzają, choć prawdopodobnie wolniej, podczas gdy komunikaty o niższym priorytcie mogą napotykać dłuższe opóźnienia.

Projekt obciążenia

Architekt powinien ocenić, w jaki sposób wzorzec kolejki priorytetowej może sprostać celom i zasadom omówionym w filarach platformy Azure Well-Architected Framework. Na przykład:

Filar Jak ten wzorzec obsługuje cele filaru
Decyzje projektowe dotyczące niezawodności pomagają obciążeniu stać się odporne na awarię i zapewnić, że zostanie przywrócony do w pełni funkcjonalnego stanu po wystąpieniu awarii. Oddzielenie elementów na podstawie priorytetu biznesowego umożliwia skoncentrowanie wysiłków związanych z niezawodnością na najbardziej krytycznej pracy.

- RE:02 Przepływy krytyczne
- RE:07 Zadania w tle
Wydajność pomaga wydajnie sprostać zapotrzebowaniu dzięki optymalizacjom skalowania, danych, kodu. Oddzielenie elementów na podstawie priorytetu biznesowego umożliwia skoncentrowanie wysiłków związanych z wydajnością w najbardziej czasochłonnej pracy.

- PE:09 Przepływy krytyczne

Podobnie jak w przypadku każdej decyzji projektowej, należy rozważyć wszelkie kompromisy w stosunku do celów innych filarów, które mogą zostać wprowadzone przy użyciu tego wzorca.

Przykład wzorca kolejki priorytetu

W poniższym przykładzie w usłudze GitHub pokazano implementację wzorca kolejki priorytetów przy użyciu usługi Azure Service Bus.

Diagram przedstawiający sposób implementowania kolejki priorytetu przy użyciu usługi Service Bus.
Rysunek 4. Architektura przykładu PriorityQueue w usłudze GitHub

Oto omówienie architektury:

  • Aplikacja (producent): Przykład zawiera aplikację (PriorityQueueSender), która tworzy komunikaty i przypisuje właściwość niestandardową o nazwie Priority w każdym komunikacie. Priority ma wartość High lub Low.

  • Broker komunikatów i kolejki: w przykładzie użyto usługi Azure Service Bus jako brokera komunikatów. Używa dwóch kolejek usługi Azure Service Bus, po jednym dla każdego priorytetu komunikatu (High i Low). Aplikacja (producent) wysyła komunikaty do właściwej kolejki na podstawie komunikatu Priority.

  • Wiele pul odbiorców: w przykładzie użyto wielu pul odbiorców (PriorityQueueConsumerHigh i PriorityQueueConsumerLow) przeznaczonych do odczytywania komunikatów z każdej z kolejek.

Rola w przykładowej architekturze Przykładowa usługa platformy Azure Nazwa w przykładzie
Aplikacja Aplikacja usługi Azure Functions PriorityQueueSender
Broker kolejek komunikatów Azure Service Bus <przestrzeń nazw usługi Service Bus>
Kolejki komunikatów Kolejki usługi Azure Service Bus <nazwy kolejek>
Klienci Aplikacja usługi Azure Functions PriorityQueueConsumerHigh
PriorityQueueConsumerLow

Podczas implementowania tego wzorca mogą być przydatne następujące wzorce:

  • Wzorzec konkurujących odbiorców: ten wzorzec obejmuje zaimplementowanie wielu odbiorców, którzy nasłuchują tych samych zadań kolejki i przetwarzania równolegle w celu zwiększenia przepływności. Tylko jeden użytkownik przetwarza każdy komunikat. Artykuł zawiera szczegółowe informacje na temat zalet i wad tego podejścia.

  • Wzorzec ograniczania przepustowości: ten wzorzec można zaimplementować przy użyciu kolejek do zarządzania szybkościami żądań. Korzystając z komunikatów priorytetowych, żądania od krytycznych aplikacji lub klientów o wysokiej wartości mogą być priorytetowe w przypadku mniej ważnych.