Wzorzec wyrównywania obciążeń przy użyciu kolejki

Azure Functions
Azure Service Bus

Użyj kolejki, która działa jako bufor między zadaniem a usługą, którą wywołuje, aby wygładzić sporadyczne duże obciążenia, które mogą spowodować niepowodzenie usługi lub przekroczenie limitu czasu zadania. Może to pomóc zminimalizować wpływ szczytów zapotrzebowania na dostępność i czas odpowiedzi zarówno dla zadania, jak i usługi.

Kontekst i problem

Wiele rozwiązań w chmurze obejmuje uruchamianie zadań wywołujących usługi. W tym środowisku sporadyczne duże obciążenia, jakim podlega usługa, mogą powodować problemy z wydajnością lub niezawodnością.

Usługa może być częścią tego samego rozwiązania co zadania, które go używają, ale może też być usługą innej firmy zapewniającą dostęp do często używanych zasobów, takich jak pamięć podręczna lub usługa magazynu. Jeśli ta sama usługa jest używana przez wiele zadań uruchomionych jednocześnie, przewidzenie w dowolnym momencie liczby żądań do usługi może być trudne.

W ramach usługi mogą wystąpić szczytowe zapotrzebowania, które powodują jej przeciążenie i uniemożliwiają reagowanie na żądania w określonym czasie. Zalewanie usługi dużą liczbą jednoczesnych żądań może także powodować niepowodzenia usługi, jeśli nie jest ona w stanie obsłużyć rywalizacji wywołanej przez te żądania.

Rozwiązanie

Refaktoryzuj rozwiązanie i wprowadź kolejkę między zadanie a usługę. Zadania i usługi działają asynchronicznie. Zadanie publikuje komunikat zawierający dane wymagane przez usługę w kolejce. Kolejka pełni rolę bufora, który przechowuje komunikat, dopóki nie zostanie pobrany przez usługę. Usługa pobiera komunikaty z kolejki i przetwarza je. Żądania pochodzące z wielu zadań, które mogą być generowane z bardzo zmienną szybkością, można przekazywać do usługi za pośrednictwem tej samej kolejki komunikatów. Poniższy rysunek pokazuje proces wyrównywania obciążenia usługi za pomocą kolejki.

Rysunek 1. Wyrównywanie obciążenia usługi za pomocą kolejki

Kolejka oddziela zadania od usługi, dlatego usługa może obsługiwać komunikaty we własnym tempie, niezależnie od liczby żądań pochodzących z jednoczesnych zadań. Ponadto opóźnienia nie dotyczą zadań, które publikują komunikat w kolejce w momencie, gdy usługa jest niedostępna.

Ten wzorzec zapewnia następujące korzyści:

  • Może pomóc zwiększyć dostępność, ponieważ opóźnienia powstające w usługach nie będą miały natychmiastowego i bezpośredniego wpływu na aplikację, która może nadal publikować komunikaty w kolejce, nawet jeśli usługa nie jest dostępna lub aktualnie nie przetwarza komunikatów.

  • Może pomóc zmaksymalizować skalowalność, ponieważ pozwala zmieniać zarówno liczbę kolejek, jak i liczbę usług w zależności od potrzeb.

  • Może pomóc w kontrolowaniu kosztów, ponieważ liczba wdrożonych wystąpień usług musi być wystarczająca, aby sprostać średniemu obciążeniu, a nie obciążeniu szczytowemu.

    Niektóre usługi implementują ograniczanie przepływności, gdy zapotrzebowanie osiąga próg, po przekroczeniu którego system może przestać działać. Ograniczanie przepływności może zmniejszyć dostępność funkcji. Aby mieć pewność, że ten próg nie zostanie osiągnięty, można zaimplementować wyrównywanie obciążenia za pomocą tych usług.

Problemy i kwestie do rozważenia

Podczas podejmowania decyzji o sposobie wdrożenia tego wzorca należy rozważyć następujące punkty:

  • Aby uniknąć przeciążenia zasobu docelowego, konieczne jest zaimplementowanie logiki aplikacji, która kontroluje szybkość, z jaką usługi obsługują komunikaty. Należy unikać przekazywania skoków zapotrzebowania do kolejnego etapu systemu. W tym celu przetestuj system pod obciążeniem, aby upewnić się, że zapewnia wymagane wyrównywanie, i dostosuj liczbę kolejek oraz liczbę wystąpień usług, które obsługują komunikaty.
  • Kolejki komunikatów to mechanizm komunikacji jednokierunkowej. Jeśli zadanie oczekuje odpowiedzi z usługi, może być konieczne zaimplementowanie mechanizmu wykorzystywanego przez usługę do wysłania odpowiedzi. Aby uzyskać więcej informacji, zobacz Asynchronous Messaging Primer (Podstawy asynchronicznej obsługi komunikatów).
  • Zachowaj ostrożność, jeśli stosujesz skalowanie automatyczne do usług, które nasłuchują żądań w kolejce. Może to spowodować nasilenie rywalizacji o dowolne zasoby, które są przez te usługi udostępniane, oraz zmniejszenie efektywności korzystania z kolejki w celu wyrównania obciążenia.
  • W zależności od obciążenia usługi można napotkać sytuacje, w których skutecznie zawsze kończy się, gdzie system zawsze kolejkuje więcej żądań niż przetwarzasz. Należy wziąć pod uwagę zmienność ruchu przychodzącego do aplikacji
  • Wzorzec może utracić informacje w zależności od trwałości kolejki. Jeśli kolejka ulega awarii lub usuwa informacje (z powodu limitów systemu), istnieje możliwość, że nie masz gwarantowanego dostarczania. Zachowanie kolejki i limitów systemowych należy wziąć pod uwagę na podstawie potrzeb rozwiązania.

Kiedy używać tego wzorca

Ten wzorzec jest przydatny w przypadku każdej aplikacji korzystającej z usług podlegających przeciążeniu.

Ten wzór nie jest przydatny, jeśli aplikacja oczekuje odpowiedzi z usługi z minimalnym opóźnieniem.

Projekt obciążenia

Architekt powinien ocenić, w jaki sposób wzorzec bilansowania obciążenia opartego na kolejce może być używany w projekcie obciążenia, aby sprostać celom i zasadom opisanym 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. Podejście opisane w tym wzorcu może zapewnić odporność na nagłe skoki zapotrzebowania przez oddzielenie przybycia zadań z ich przetwarzania. Może również odizolować awarie przetwarzania kolejek, aby nie wpływały na spożycie.

- PONOWNE:06 Skalowanie
- RE:07 Zadania w tle
Optymalizacja kosztów koncentruje się na utrzymaniu i poprawie zwrotu obciążenia z inwestycji. Ponieważ przetwarzanie obciążenia jest oddzielone od żądania lub wprowadzania zadań, można użyć tego podejścia, aby zmniejszyć potrzebę nadmiernej aprowizacji zasobów w celu obsługi szczytowego obciążenia.

- CO:12 Koszty skalowania
Wydajność pomagawydajnie sprostać zapotrzebowaniu dzięki optymalizacjom skalowania, danych, kodu. Takie podejście umożliwia zamierzone projektowanie wydajności przepływności, ponieważ pobieranie żądań nie musi być skorelowane z szybkością przetwarzania.

- PE:05 Skalowanie i partycjonowanie

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

Aplikacja internetowa zapisuje dane w zewnętrznym magazynie danych. Jeśli wiele wystąpień aplikacji internetowej jest uruchamianych współbieżnie, magazyn danych może nie odpowiadać na żądania wystarczająco szybko, powodując przekroczenie limitu czasu żądań, ograniczenie przepustowości lub niepowodzenie w inny sposób. Na poniższym diagramie pokazano, że magazyn danych jest przytłoczony dużą liczbą współbieżnych żądań z wystąpień aplikacji.

Rysunek 2. Usługa przeciążona dużą liczbą współbieżnych żądań z wystąpień aplikacji internetowej

Aby rozwiązać ten problem, możesz użyć kolejki, aby wyrównać obciążenie między wystąpieniami aplikacji a magazynem danych. Aplikacja usługi Azure Functions odczytuje komunikaty z kolejki i wykonuje żądania odczytu/zapisu w magazynie danych. Logika aplikacji w aplikacji funkcji może kontrolować szybkość, z jaką przekazuje żądania do magazynu danych, aby zapobiec przeciążeniu magazynu. (W przeciwnym razie aplikacja funkcji po prostu ponownie wprowadzi ten sam problem na zapleczu).

Rysunek 3. Używanie kolejki i aplikacji funkcji w celu wyrównania obciążenia

Następne kroki

Podczas implementowania tego wzorca mogą być istotne następujące wskazówki:

  • Asynchronous Messaging Primer (Podstawy asynchronicznej obsługi komunikatów). Kolejki komunikatów są z założenia asynchroniczne. Może być konieczne zmodyfikowanie logiki aplikacji w zadaniu, jeśli została przystosowana do korzystania z kolejki komunikatów zamiast bezpośredniego komunikowania się z usługą. Konieczne może być też refaktoryzowanie usługi w taki sposób, aby akceptowała żądania z kolejki komunikatów. Alternatywnie można również zaimplementować usługę proxy, co zostało opisane w przykładzie.

  • Wybierz między usługami obsługi komunikatów platformy Azure. Informacje na temat wybierania mechanizmu do obsługi komunikatów i kolejkowania w aplikacjach platformy Azure.

  • Asynchroniczna komunikacja oparta na komunikatach.

  • Styl architektury Web-Queue-Worker. Element internetowy i proces roboczy są bezstanowe. Stan sesji można przechowywać w rozproszonej pamięci podręcznej. Wszystkie długotrwałe zadania są wykonywane asynchronicznie przez proces roboczy. Proces roboczy może być wyzwalany przez komunikaty w kolejce lub uruchamiany zgodnie z harmonogramem przetwarzania wsadowego.

Podczas implementowania tego wzorca mogą być również istotne następujące wzorce:

  • Wzorzec konkurujących odbiorców. Jest możliwość uruchomienia wielu wystąpień usługi, z których każde pełni rolę konsumenta komunikatów przychodzących z kolejki wyrównywania obciążenia. Takie podejście umożliwia dostosowanie szybkości, z jaką usługa odbiera i przekazuje komunikaty.

  • Wzorzec ograniczania przepływności. Prosty sposób na zaimplementowanie ograniczania przepływności usługi polega na wykorzystaniu wyrównywania obciążenia przy użyciu kolejki i przekierowaniu wszystkich żądań do usługi za pośrednictwem kolejki komunikatów. Usługa może przetwarzać żądania z szybkością, która zapewnia, że zasoby wymagane przez usługę nie zostaną wyczerpane, oraz zmniejszać liczbę rywalizacji, które mogłyby wystąpić.