Projektowanie odpornych usług Event Hubs i Functions

Obsługa błędów, projektowanie pod kątem idempotencji i zarządzanie zachowaniem ponawiania prób to kilka krytycznych środków, które można podjąć, aby zagwarantować, że wyzwalane funkcje usługi Event Hubs są odporne i mogą obsługiwać duże ilości danych. W tym artykule omówiono te kluczowe pojęcia i przedstawiono zalecenia dotyczące rozwiązań do przesyłania strumieniowego zdarzeń bezserwerowych.

Platforma Azure udostępnia trzy główne usługi obsługi komunikatów, których można używać z Azure Functions do obsługi szerokiej gamy unikatowych scenariuszy opartych na zdarzeniach. Ze względu na partycjonowany model konsumentów i możliwość pozyskiwania danych o wysokiej szybkości, Azure Event Hubs jest często używany w scenariuszach przesyłania strumieniowego zdarzeń i danych big data. Aby uzyskać szczegółowe porównanie usług obsługi komunikatów platformy Azure, zobacz Wybieranie między usługami obsługi komunikatów platformy Azure — Event Grid, Event Hubs i Service Bus.

Korzyści i wyzwania związane z przesyłaniem strumieniowym

Zrozumienie korzyści i wad strumieni pomaga docenić sposób działania usługi, takiej jak Event Hubs . Ten kontekst jest również potrzebny podczas podejmowania decyzji dotyczących architektury, rozwiązywania problemów i optymalizowania pod kątem wydajności. Należy wziąć pod uwagę następujące kluczowe pojęcia dotyczące rozwiązań z usługą Event Hubs i usługą Functions:

  • Strumienie nie są kolejkami: Usługi Event Hubs, Kafka i inne podobne oferty, które są oparte na modelu partycjonowanego konsumenta, nie obsługują wewnętrznie niektórych funkcji głównych w brokerze komunikatów, takim jak Service Bus. Być może największym wskaźnikiem tego jest fakt, że odczyty są nie destrukcyjne. Oznacza to, że dane odczytywane przez hosta usługi Functions nie są usuwane później. Zamiast tego komunikaty są niezmienne i pozostają dla innych konsumentów do odczytania, w tym potencjalnie tego samego klienta odczytu. Z tego powodu rozwiązania, które implementują wzorce, takie jak konkurujący konsumenci , są lepiej dostosowane do tradycyjnego brokera komunikatów.

  • Brak wbudowanej obsługi utraconych wiadomości: Kanał utraconych wiadomości nie jest funkcją natywną w usłudze Event Hubs ani na platformie Kafka. Często koncepcja martwych listów jest zintegrowana z rozwiązaniem przesyłania strumieniowego w celu uwzględnienia danych, których nie można przetworzyć. Ta funkcja celowo nie jest elementem wrodzonym w usłudze Event Hubs i jest dodawana tylko po stronie konsumenta, aby wyprodukować podobne zachowanie lub efekt. Jeśli potrzebujesz obsługi utraconych wiadomości, możesz potencjalnie przejrzeć wybór usługi przesyłania strumieniowego wiadomości.

  • Jednostka pracy to partycja: W tradycyjnym brokerze komunikatów jednostka pracy jest pojedynczym komunikatem. W rozwiązaniu do przesyłania strumieniowego partycja jest często uznawana za jednostkę pracy. Jeśli każde zdarzenie w centrum zdarzeń jest traktowane jako dyskretny komunikat, który wymaga, aby był traktowany jak operacja przetwarzania zamówień lub transakcji finansowej, najprawdopodobniej jest to wskazanie nieprawidłowej usługi obsługi komunikatów.

  • Brak filtrowania po stronie serwera: Jednym z powodów, dla których usługa Event Hubs może mieć ogromną skalę, a przepływność jest spowodowana niskim obciążeniem w samej usłudze. Funkcje takie jak filtrowanie po stronie serwera, indeksy i koordynacja między brokerami nie są częścią architektury usługi Event Hubs. Funkcje są czasami używane do filtrowania zdarzeń przez kierowanie ich do innych usług Event Hubs na podstawie zawartości treści lub nagłówka. Takie podejście jest powszechne w przypadku przesyłania strumieniowego zdarzeń, ale wiąże się z zastrzeżeniem, że każde zdarzenie jest odczytywane i oceniane przez funkcję początkową.

  • Każdy czytelnik musi odczytać wszystkie dane: Ponieważ filtrowanie po stronie serwera jest niedostępne, użytkownik sekwencyjnie odczytuje wszystkie dane w partycji. Obejmuje to dane, które mogą nie być istotne lub mogą być źle sformułowane. Istnieje kilka opcji, a nawet strategii, które mogą służyć do zrekompensowania tych wyzwań, które zostaną omówione w dalszej części tej sekcji.

Te znaczące decyzje projektowe umożliwiają usłudze Event Hubs wykonywanie najlepszych czynności: obsługę znacznego napływu zdarzeń i zapewnienie niezawodnej i odpornej usługi dla użytkowników do odczytu. Każda aplikacja odbiorcza jest odpowiedzialna za utrzymywanie własnych, przesunięć po stronie klienta lub kursora na te zdarzenia. Niskie obciążenie sprawia, że usługa Event Hubs jest przystępną cenowo i zaawansowaną opcją przesyłania strumieniowego zdarzeń.

Idempotencyjność

Jednym z podstawowych zestawów Azure Event Hubs jest koncepcja co najmniej raz dostawy. Takie podejście zapewnia, że zdarzenia będą zawsze dostarczane. Oznacza to również, że zdarzenia mogą być odbierane więcej niż raz, nawet wielokrotnie, przez konsumentów, takich jak funkcja. Z tego powodu ważne jest, aby funkcja wyzwalana przez centrum zdarzeń obsługiwała wzorzec idempotentnego konsumenta .

Praca przy założeniu co najmniej raz dostarczania, zwłaszcza w kontekście architektury opartej na zdarzeniach, jest odpowiedzialnym podejściem do niezawodnego przetwarzania zdarzeń. Funkcja musi być idempotentna, aby wynik przetwarzania tego samego zdarzenia wiele razy był taki sam jak przetwarzanie go raz.

Zduplikowane zdarzenia

Istnieje kilka różnych scenariuszy, które mogą spowodować dostarczenie zduplikowanych zdarzeń do funkcji:

  • Tworzenie punktów kontrolnych: Jeśli host Azure Functions ulegnie awarii lub próg ustawiony dla częstotliwości punktu kontrolnego wsadowego nie zostanie spełniony, punkt kontrolny nie zostanie utworzony. W rezultacie przesunięcie dla konsumenta nie jest zaawansowane i następnym wywołaniu funkcji zostanie wznowiona z ostatniego punktu kontrolnego. Należy pamiętać, że punkt kontrolny występuje na poziomie partycji dla każdego konsumenta.

  • Opublikowane zduplikowane zdarzenia: Istnieje wiele technik, które mogłyby złagodzić możliwość opublikowania tego samego zdarzenia w strumieniu, jednak nadal jest to odpowiedzialność konsumenta za idempotentnie obsługiwać duplikaty.

  • Brak potwierdzenia: W niektórych sytuacjach wychodzące żądanie do usługi może zakończyć się powodzeniem, jednak potwierdzenie (ACK) z usługi nigdy nie zostanie odebrane. Może to spowodować postrzeganie, że wywołanie wychodzące nie powiodło się i zainicjowało serię lub ponawianie prób lub inne wyniki z funkcji. W końcu można opublikować zduplikowane zdarzenia lub punkt kontrolny nie jest tworzony.

Techniki deduplikacji

Projektowanie funkcji dla identycznych danych wejściowych powinno być podejściem domyślnym podjętym podczas łączenia z powiązaniem wyzwalacza centrum zdarzeń. Należy wziąć pod uwagę następujące techniki:

  • Szukasz duplikatów: Przed przetworzeniem wykonaj niezbędne kroki, aby sprawdzić, czy zdarzenie powinno zostać przetworzone. W niektórych przypadkach wymaga to badania, aby potwierdzić, że jest ona nadal prawidłowa. Może być również możliwe, że obsługa zdarzenia nie jest już konieczna ze względu na świeżość danych lub logikę, która unieważnia zdarzenie.

  • Zdarzenia projektu dla idempotencji: Podając dodatkowe informacje w ładunku zdarzenia, może być możliwe zapewnienie, że przetwarzanie go wiele razy nie będzie miało żadnych szkodliwych skutków. Weźmy przykład zdarzenia, które obejmuje kwotę wypłaty z konta bankowego. Jeśli nie są obsługiwane w sposób odpowiedzialny, istnieje możliwość wielokrotnego dekrementowania salda konta. Jeśli jednak to samo zdarzenie zawiera zaktualizowane saldo na koncie, można użyć go do wykonania operacji upsert na saldo konta bankowego. Takie podejście do transferu państwa prowadzone od czasu do czasu wymaga koordynacji między producentami a konsumentami i powinno być stosowane, gdy ma to sens dla uczestniczących usług.

Obsługa błędów oraz wykonywanie ponownych prób

Obsługa błędów i ponawianie prób to kilka najważniejszych cech aplikacji rozproszonych, opartych na zdarzeniach, a funkcje nie są wyjątkiem. W przypadku rozwiązań do przesyłania strumieniowego zdarzeń niezbędna jest odpowiednia obsługa błędów, ponieważ tysiące zdarzeń może szybko przekształcić się w taką samą liczbę błędów, jeśli nie są one prawidłowo obsługiwane.

Wskazówki dotyczące obsługi błędów

Bez obsługi błędów może być trudne zaimplementowanie ponownych prób, wykrywanie wyjątków środowiska uruchomieniowego i badanie problemów. Każda funkcja powinna mieć co najmniej pewien poziom lub obsługę błędów. Oto kilka zalecanych wytycznych:

  • Użyj usługi Application Insights: Włącz i użyj usługi Application Insights, aby rejestrować błędy i monitorować kondycję funkcji. Należy pamiętać o konfigurowalnych opcjach próbkowania dla scenariuszy, które przetwarzają dużą liczbę zdarzeń.

  • Dodaj obsługę ustrukturyzowanych błędów: Zastosuj odpowiednie konstrukcje obsługi błędów dla każdego języka programowania, aby przechwytywać, rejestrować i wykrywać przewidywane i nieobsługiwane wyjątki w kodzie funkcji. Na przykład użyj bloku try/catch w języku C#, Java i JavaScript oraz skorzystaj z funkcji wypróbuj i z wyjątkiem bloków w języku Python, aby obsłużyć wyjątki.

  • Rejestrowania: Przechwycenie wyjątku podczas wykonywania zapewnia możliwość rejestrowania krytycznych informacji, które mogą służyć do wykrywania, odtwarzania i rozwiązywania problemów w sposób niezawodny. Zarejestruj wyjątek, nie tylko komunikat, ale treść, wyjątek wewnętrzny i inne przydatne artefakty, które będą przydatne później.

  • Nie przechwytuj i ignoruj wyjątki: Jedną z najgorszych rzeczy, które można zrobić, jest przechwycenie wyjątku i nic z nim zrobić. Jeśli przechwycisz wyjątek ogólny, zarejestruj go gdzieś. Jeśli nie rejestrujesz błędów, trudno jest zbadać usterki i zgłosić problemy.

Ponowne próby

Implementacja logiki ponawiania w architekturze przesyłania strumieniowego zdarzeń może być złożona. Obsługa tokenów anulowania, liczby ponownych prób i strategii wycofywania wykładniczego to tylko kilka zagadnień, które sprawiają, że jest to trudne. Na szczęście usługa Functions udostępnia zasady ponawiania prób, które mogą nadrobić wiele z tych zadań, które zwykle samodzielnie kodujesz.

W przypadku korzystania z zasad ponawiania prób z powiązaniem centrum zdarzeń należy wziąć pod uwagę kilka ważnych czynników:

  • Unikaj nieokreślonych ponownych prób: Gdy ustawienie maksymalnej liczby ponownych prób zostanie ustawione na wartość -1, funkcja ponowi próbę na czas nieokreślony. Ogólnie rzecz biorąc, ponowne próby na czas nieokreślony powinny być używane oszczędnie z usługami Functions i prawie nigdy z powiązaniem wyzwalacza centrum zdarzeń.

  • Wybierz odpowiednią strategię ponawiania prób: Strategia o stałym opóźnieniu może być optymalna dla scenariuszy, które odbierają presję wsteczną z innych usług platformy Azure. W takich przypadkach opóźnienie może pomóc uniknąć ograniczania przepustowości i innych ograniczeń napotkanych z tych usług. Strategia wycofywania wykładniczego zapewnia większą elastyczność w przypadku interwałów opóźnień ponawiania prób i jest często używana podczas integrowania z usługami innych firm, punktami końcowymi REST i innymi usługami platformy Azure.

  • Zachowaj niskie interwały i ponawianie prób: Jeśli to możliwe, spróbuj zachować interwał ponawiania prób krótszy niż minutę. Ponadto należy zachować maksymalną liczbę prób ponawiania prób w rozsądnie niskiej liczbie. Te ustawienia są szczególnie istotne podczas uruchamiania w planie Zużycie funkcji.

  • Wzorzec wyłącznika: Oczekiwany jest przejściowy błąd błędu od czasu do czasu i naturalny przypadek użycia ponownych prób. Jeśli jednak podczas przetwarzania funkcji występuje znaczna liczba błędów lub problemów, warto zatrzymać funkcję, rozwiązać problemy i uruchomić ponownie później.

Ważnym rozwiązaniem dla zasad ponawiania prób w usłudze Functions jest to, że jest to najlepsza funkcja ponownego przetwarzania zdarzeń. Nie zastępuje potrzeby obsługi błędów, rejestrowania i innych ważnych wzorców zapewniających odporność na kod.

Strategie dotyczące niepowodzeń i uszkodzonych danych

Istnieje kilka godnych uwagi podejść, których można użyć do zrekompensowania problemów, które pojawiają się z powodu awarii lub nieprawidłowych danych w strumieniu zdarzeń. Oto niektóre podstawowe strategie:

  • Przestań wysyłać i odczytywać: Wstrzymywanie odczytywania i zapisywania zdarzeń w celu rozwiązania podstawowego problemu. Zaletą tego podejścia jest to, że dane nie zostaną utracone, a operacje mogą zostać wznowione po wdrożeniu poprawki. Takie podejście może wymagać składnika wyłącznika w architekturze i ewentualnie powiadomienia do usług, których dotyczy problem, w celu osiągnięcia wstrzymania. W niektórych przypadkach zatrzymanie funkcji może być konieczne do momentu rozwiązania problemów.

  • Upuszczanie komunikatów: Jeśli komunikaty nie są ważne lub są uważane za niekrytyczne, rozważ przejście i nie przetwarzaj ich. Nie działa to w scenariuszach wymagających silnej spójności, takich jak rejestrowanie ruchów w meczu szachowym lub transakcjach opartych na finansach. Obsługa błędów wewnątrz funkcji jest zalecana do przechwytywania i usuwania komunikatów, których nie można przetworzyć.

  • Ponów próbę: Istnieje wiele sytuacji, które mogą uzasadniać ponowne przetwarzanie zdarzenia. Najbardziej typowym scenariuszem jest błąd przejściowy napotkany podczas wywoływania innej usługi lub zależności. Błędy sieci, limity usług i dostępność oraz silna spójność są prawdopodobnie najczęstszymi przypadkami użycia, które uzasadniają próby ponownego przetwarzania.

  • Utracony list: Oto pomysł, aby opublikować zdarzenie w innym centrum zdarzeń, aby istniejący przepływ nie został przerwany. Postrzeganie polega na tym, że został przeniesiony z gorącej ścieżki i może być traktowany później lub przez inny proces. To rozwiązanie jest często używane do obsługi zatrutych komunikatów lub zdarzeń. Należy zauważyć, że każda funkcja, która jest skonfigurowana z inną grupą odbiorców, nadal napotka nieprawidłowe lub uszkodzone dane w strumieniu i musi obsługiwać je w sposób odpowiedzialny.

  • Ponów próbę i utracony list: Połączenie wielu prób ponawiania prób przed ostatecznym opublikowaniem strumienia utraconych listów po osiągnięciu progu jest inną znaną metodą.

  • Użyj rejestru schematów: Rejestr schematów może służyć jako proaktywne narzędzie, aby poprawić spójność i jakość danych. Rejestr schematów platformy Azure może obsługiwać przechodzenie schematów wraz z trybami przechowywania wersji i różnymi trybami zgodności w miarę rozwoju schematów. W jego ramach schemat będzie służyć jako umowa między producentami i konsumentami, co może zmniejszyć możliwość opublikowania nieprawidłowych lub uszkodzonych danych do strumienia.

W końcu nie ma idealnego rozwiązania, a konsekwencje i kompromisy poszczególnych strategii należy dokładnie zbadać. W oparciu o wymagania, użycie kilku z tych technik może być najlepszym podejściem.

Współautorzy

Ten artykuł jest obsługiwany przez firmę Microsoft. Pierwotnie został napisany przez następujących współautorów.

Główny autor:

Aby wyświetlić niepubliowe profile usługi LinkedIn, zaloguj się do serwisu LinkedIn.

Następne kroki

Przed kontynuowaniem rozważ przejrzenie następujących powiązanych artykułów: