Azure Functions niezawodne przetwarzanie zdarzeń

Przetwarzanie zdarzeń jest jednym z najbardziej typowych scenariuszy związanych z architekturą bezserwerową. W tym artykule opisano sposób tworzenia niezawodnego procesora komunikatów przy użyciu Azure Functions, aby uniknąć utraty komunikatów.

Wyzwania związane ze strumieniami zdarzeń w systemach rozproszonych

Rozważ system, który wysyła zdarzenia ze stałą szybkością 100 zdarzeń na sekundę. W tym tempie w ciągu kilku minut wiele równoległych wystąpień usługi Functions może zużywać 100 przychodzących zdarzeń co sekundę.

Możliwe są jednak dowolne z następujących warunków mniej optymalnych:

  • Co zrobić, jeśli wydawca zdarzeń wyśle uszkodzone zdarzenie?
  • Co zrobić, jeśli wystąpienie usługi Functions napotka nieobsługiwane wyjątki?
  • Co zrobić, jeśli system podrzędny przejdzie w tryb offline?

Jak poradzić sobie z tymi sytuacjami przy zachowaniu przepływności aplikacji?

Dzięki kolejkom niezawodna obsługa komunikatów jest naturalnie dostarczana. Po połączeniu z wyzwalaczem usługi Functions funkcja tworzy blokadę w komunikacie kolejki. Jeśli przetwarzanie nie powiedzie się, blokada zostanie zwolniona, aby umożliwić innemu wystąpieniu ponowienie próby przetworzenia. Przetwarzanie będzie kontynuowane do momentu pomyślnego obliczenia komunikatu lub dodania go do kolejki trucizny.

Nawet jeśli pojedynczy komunikat w kolejce może pozostać w cyklu ponawiania, inne równoległe wykonania nadal będą usuwać pozostałe komunikaty z kolejki. W rezultacie ogólna przepływność pozostaje w dużej mierze bez wpływu na jeden zły komunikat. Jednak kolejki magazynu nie gwarantują kolejności i nie są zoptymalizowane pod kątem wymagań dotyczących wysokiej przepływności wymaganych przez usługę Event Hubs.

Z kolei Azure Event Hubs nie obejmuje koncepcji blokowania. Aby umożliwić korzystanie z funkcji, takich jak wysoka przepływność, wiele grup odbiorców i możliwość odtwarzania, zdarzenia usługi Event Hubs zachowują się bardziej jak odtwarzacz wideo. Zdarzenia są odczytywane z pojedynczego punktu w strumieniu na partycję. Ze wskaźnika można odczytać do przodu lub do tyłu z tej lokalizacji, ale musisz wybrać przeniesienie wskaźnika dla zdarzeń do przetworzenia.

Jeśli wystąpią błędy w strumieniu, jeśli zdecydujesz się zachować wskaźnik w tym samym miejscu, przetwarzanie zdarzeń jest blokowane do momentu zaawansowanego wskaźnika. Innymi słowy, jeśli wskaźnik zostanie zatrzymany w celu radzenia sobie z problemami z przetwarzaniem pojedynczego zdarzenia, nieprzetworzone zdarzenia zaczynają się stosować.

Azure Functions unika zakleszczenia, posuwając wskaźnik strumienia niezależnie od powodzenia lub niepowodzenia. Ponieważ wskaźnik ciągle się rozwija, funkcje muszą odpowiednio radzić sobie z błędami.

Jak Azure Functions korzysta ze zdarzeń usługi Event Hubs

Azure Functions używa zdarzeń centrum zdarzeń podczas jazdy na rowerze, wykonując następujące kroki:

  1. Wskaźnik jest tworzony i utrwalany w usłudze Azure Storage dla każdej partycji centrum zdarzeń.
  2. Po odebraniu nowych komunikatów (domyślnie w partii) host próbuje wyzwolić funkcję za pomocą partii komunikatów.
  3. Jeśli funkcja zakończy wykonywanie (z wyjątkiem lub bez wyjątku), wskaźnik zostanie zapisany i punkt kontrolny zostanie zapisany na koncie magazynu.
  4. Jeśli warunki uniemożliwiają ukończenie wykonywania funkcji, host nie może przejść przez wskaźnik. Jeśli wskaźnik nie jest zaawansowany, późniejsze kontrole kończą się przetwarzaniem tych samych komunikatów.
  5. Powtórz kroki 2–4

To zachowanie ujawnia kilka ważnych kwestii:

Obsługa wyjątków

Ogólnie rzecz biorąc, każda funkcja powinna zawierać blok try/catch na najwyższym poziomie kodu. W szczególności wszystkie funkcje, które używają zdarzeń usługi Event Hubs, powinny mieć catch blok. W ten sposób, gdy zostanie zgłoszony wyjątek, blok catch obsługuje błąd przed postępem wskaźnika.

Mechanizmy i zasady ponawiania prób

Niektóre wyjątki są z natury przejściowe i nie pojawiają się ponownie, gdy operacja zostanie podjęta ponownie chwilę później. Dlatego pierwszym krokiem jest zawsze ponowienie próby wykonania operacji. W ramach wykonywania funkcji możesz użyć zasad ponawiania próby aplikacji funkcji lub utworzyć logikę ponawiania prób.

Wprowadzenie do funkcji zachowania obsługi błędów umożliwia zdefiniowanie zarówno podstawowych, jak i zaawansowanych zasad ponawiania. Można na przykład zaimplementować zasady, które są zgodne z przepływem pracy zilustrowanym przez następujące reguły:

  • Spróbuj wstawić komunikat trzy razy (potencjalnie z opóźnieniem między ponownymi próbami).
  • Jeśli ostateczny wynik wszystkich ponownych prób jest niepowodzeniem, dodaj komunikat do kolejki, aby przetwarzanie było kontynuowane w strumieniu.
  • Uszkodzone lub nieprzetworzone komunikaty są następnie obsługiwane później.

Uwaga

Polly to przykład odporności i biblioteki obsługi błędów przejściowych dla aplikacji języka C#.

Błędy niezwiązane z wyjątkiem

Niektóre problemy występują nawet wtedy, gdy błąd nie istnieje. Rozważmy na przykład błąd, który występuje w trakcie wykonywania. W takim przypadku, jeśli funkcja nie ukończy wykonywania, wskaźnik przesunięcia nigdy nie będzie przechodził. Jeśli wskaźnik nie zostanie uruchomiony, każde wystąpienie uruchamiane po nieudanym wykonaniu będzie nadal odczytywać te same komunikaty. Ta sytuacja zapewnia gwarancję "co najmniej raz".

Zapewnienie, że każdy komunikat jest przetwarzany co najmniej raz, oznacza, że niektóre komunikaty mogą być przetwarzane więcej niż raz. Aplikacje funkcji muszą mieć świadomość tej możliwości i muszą być tworzone zgodnie z zasadami idempotentności.

Zatrzymywanie i ponowne uruchamianie wykonywania

Chociaż kilka błędów może być akceptowalnych, co zrobić, jeśli aplikacja napotka znaczne błędy? Możesz zatrzymać wyzwalanie zdarzeń, dopóki system nie osiągnie stanu dobrej kondycji. Możliwość wstrzymania przetwarzania jest często osiągana za pomocą wzorca wyłącznika. Wzorzec wyłącznika umożliwia aplikacji "przerwanie obwodu" procesu zdarzenia i wznowienie w późniejszym czasie.

Istnieją dwa elementy wymagane do zaimplementowania wyłącznika w procesie zdarzenia:

  • Stan udostępniony we wszystkich wystąpieniach w celu śledzenia i monitorowania kondycji obwodu
  • Proces główny, który może zarządzać stanem obwodu (otwarty lub zamknięty)

Szczegóły implementacji mogą się różnić, ale aby współużytkować stan między wystąpieniami, potrzebny jest mechanizm magazynu. Możesz zdecydować się na przechowywanie stanu w usłudze Azure Storage, pamięci podręcznej Redis lub innym koncie dostępnym dla kolekcji funkcji.

Usługa Azure Logic Apps lub trwałe funkcje są naturalnym rozwiązaniem do zarządzania przepływem pracy i stanem obwodu. Inne usługi mogą działać równie dobrze, ale aplikacje logiki są używane w tym przykładzie. Za pomocą aplikacji logiki można wstrzymać i ponownie uruchomić wykonywanie funkcji, co daje kontrolę wymaganą do zaimplementowania wzorca wyłącznika.

Definiowanie progu awarii między wystąpieniami

Aby uwzględnić wiele wystąpień przetwarzania zdarzeń jednocześnie, do monitorowania kondycji obwodu potrzebne jest utrwalanie współużytkowanego stanu zewnętrznego.

Reguła, którą możesz zaimplementować, może wymuszać następujące uwierzytelnianie:

  • Jeśli w ciągu 30 sekund we wszystkich wystąpieniach wystąpień występuje więcej niż 100 awarii, przerwij obwód i zatrzymaj wyzwalanie nowych komunikatów.

Szczegóły implementacji różnią się w zależności od potrzeb, ale ogólnie można utworzyć system, który:

  1. Rejestruje błędy na koncie magazynu (Azure Storage, Redis itp.)
  2. Po zarejestrowaniu nowego błędu sprawdź liczbę kroczącą, aby sprawdzić, czy próg został osiągnięty (na przykład ponad 100 w ciągu ostatnich 30 sekund).
  3. Jeśli próg zostanie osiągnięty, wyemituj zdarzenie w celu Azure Event Grid poinformowania systemu o przerwaniu obwodu.

Zarządzanie stanem obwodu za pomocą usługi Azure Logic Apps

Poniższy opis przedstawia jeden ze sposobów tworzenia aplikacji logiki platformy Azure w celu zatrzymania przetwarzania aplikacji usługi Functions.

Usługa Azure Logic Apps zawiera wbudowane łączniki do różnych usług, funkcje orkiestracji stanowych i jest naturalnym wyborem do zarządzania stanem obwodu. Po wykryciu, że obwód musi się zepsuć, możesz utworzyć aplikację logiki w celu zaimplementowania następującego przepływu pracy:

  1. Wyzwalanie przepływu pracy usługi Event Grid i zatrzymywanie funkcji platformy Azure (za pomocą łącznika zasobów platformy Azure)
  2. Wyślij wiadomość e-mail z powiadomieniem, która zawiera opcję ponownego uruchomienia przepływu pracy

Odbiorca wiadomości e-mail może zbadać kondycję obwodu i, w razie potrzeby, ponownie uruchomić obwód za pośrednictwem linku w wiadomości e-mail z powiadomieniem. Gdy przepływ pracy ponownie uruchamia funkcję, komunikaty są przetwarzane z ostatniego punktu kontrolnego centrum zdarzeń.

Korzystając z tego podejścia, żadne komunikaty nie są tracone, wszystkie komunikaty są przetwarzane w odpowiedniej kolejności i można przerwać obwód tak długo, jak to konieczne.

Zasoby

Następne kroki

Więcej informacji można znaleźć w następujących zasobach: