Udostępnij za pośrednictwem


Projektowanie odpornych usług Event Hubs i Functions

Obsługa błędów, projektowanie pod kątem idempotentności i zarządzanie zachowaniem ponawiania to kilka krytycznych środków, które można podjąć, aby zapewnić odporność funkcji wyzwalanych przez usługę Event Hubs i możliwość obsługi dużych ilości danych. W tym artykule opisano 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 usługą Azure Functions do obsługi szerokiej gamy unikatowych scenariuszy opartych na zdarzeniach. Ze względu na partycjonowany model odbiorców i możliwość pozyskiwania danych o wysokiej szybkości usługa Azure Event Hubs jest często używana 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ć działanie usługi takiej jak Event Hubs . Ten kontekst jest również potrzebny podczas podejmowania ważnych decyzji dotyczących architektury, rozwiązywania problemów i optymalizowania pod kątem wydajności. Zapoznaj się z następującymi kluczowymi pojęciami dotyczącymi 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 podzielonym modelu 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 tych różnic jest fakt, że odczyty są niedestrukcyjne. Dzięki temu dane odczytane przez hosta usługi Functions pozostają dostępne później. Zamiast tego komunikaty są niezmienne i pozostają dla innych konsumentów do odczytania, w tym potencjalnie tego samego konsumenta odczytując go ponownie. Z tego powodu rozwiązania implementujące wzorce, takie jak konkurujący konsumenci , mogą być lepiej obsługiwane przez brokera komunikatów, takiego jak Service Bus.

  • Brak wbudowanej obsługi utraconych komunikatów: kanał utraconych wiadomości nie jest funkcją natywną w usłudze Event Hubs lub Kafka. Często koncepcja utraconych komunikatów jest zintegrowana z rozwiązaniem do 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 komunikatów, możesz potencjalnie przejrzeć wybór usługi wiadomości przesyłanych strumieniowo.

  • 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 odrębny komunikat wymagający przetwarzania zamówień lub obsługi transakcji finansowych, sugeruje możliwość zapoznania się z bardziej odpowiednią usługą obsługi komunikatów w celu uzyskania optymalnej wydajności lub przetwarzania.

  • Brak filtrowania po stronie serwera: Jednym z powodów, dla których usługa Event Hubs może mieć ogromną skalę, a przepływność wynika z niskiego obciążenia związanego z samą usługą. 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 centrów zdarzeń na podstawie zawartości treści lub nagłówka. Takie podejście jest typowe w przypadku przesyłania strumieniowego zdarzeń, ale wiąże się z zastrzeżeniem, że funkcja początkowa odczytuje i ocenia każde zdarzenie.

  • 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. Kilka opcji i strategii można użyć do zrekompensowania tych wyzwań, które zostały omówione w dalszej części tej sekcji.

Te istotne decyzje projektowe umożliwiają usłudze Event Hubs wykonywanie najlepszych działań: obsługę znaczącego napływu zdarzeń i zapewnienie niezawodnej i odpornej usługi dla użytkowników do odczytu. Każda aplikacja konsumenta 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ń.

Idempotentność

Jednym z podstawowych zestawów usługi Azure Event Hubs jest koncepcja co najmniej jednokrotnego dostarczania. Takie podejście zapewnia, że zdarzenia są 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 jednokrotnego dostarczania, zwłaszcza w kontekście architektury sterowanej zdarzeniami, 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 raz.

Zduplikowane zdarzenia

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

  • Tworzenie punktów kontrolnych: jeśli host usługi 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 związku z tym przesunięcie dla konsumenta nie jest zaawansowane i przy 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 zdarzenia zduplikowane: Wiele technik może zmniejszyć prawdopodobieństwo opublikowania tego samego zdarzenia w strumieniu, ale konsument jest nadal odpowiedzialny za obsługę duplikatów idempotentnie.

  • 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. To postrzeganie może spowodować przekonanie, że wywołanie wychodzące nie powiodło się i zainicjować serię ponownych prób lub innych wyników 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 w przypadku powiązania wyzwalacza centrum zdarzeń. Należy wziąć pod uwagę następujące techniki:

  • Wyszukiwanie 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 projektowania dla idempotentności: podając dodatkowe informacje w ładunku zdarzenia, można zagwarantować, że przetwarzanie go wiele razy nie ma żadnych szkodliwych skutków. Weźmy przykład zdarzenia, które zawiera kwotę wypłaty z konta bankowego. Jeśli nie są obsługiwane w sposób odpowiedzialny, możliwe jest, że może to spowodować wielokrotne obniżenie salda konta. Jeśli jednak to samo zdarzenie zawiera zaktualizowane saldo na koncie, można użyć go do wykonania operacji upsert na koncie bankowym. Takie podejście do transferu państwa prowadzonego 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 i 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 usługę Application Insights i użyj jej, 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ń.

  • Dodawanie obsługi błędów strukturalnych: zastosuj odpowiednie konstrukcje obsługi błędów dla każdego języka programowania, aby przechwytywać, rejestrować i wykrywać oczekiwane i nieobsługiwane wyjątki w kodzie funkcji. Na przykład użyj bloku try/catch w języku C#, Java i JavaScript, a następnie skorzystaj z bloków try i z wyjątkiem bloków w języku Python, aby obsługiwać wyjątki.

  • Rejestrowanie: przechwytywanie wyjątku podczas wykonywania zapewnia możliwość rejestrowania krytycznych informacji, których można użyć do niezawodnego wykrywania, odtwarzania i rozwiązywania problemów. Zarejestruj wyjątek, nie tylko komunikat, ale treść, wyjątek wewnętrzny i inne przydatne artefakty, które są 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łoszone problemy.

Ponowne próby

Implementowanie logiki ponawiania prób w architekturze przesyłania strumieniowego zdarzeń może być złożone. Obsługa tokenów anulowania, liczby ponownych prób i strategie 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ą składać się z wielu z tych zadań, które zwykle kodują samodzielnie.

Kilka ważnych czynników, które należy wziąć pod uwagę podczas korzystania z zasad ponawiania z powiązaniem centrum zdarzeń, obejmują:

  • Unikaj nieokreślonych ponownych prób: gdy ustawienie maksymalnej liczby ponownych prób jest ustawione na wartość -1, funkcja ponawia próbę na czas nieokreślony. Ogólnie rzecz biorąc, nieokreślone ponawianie prób powinno być używane oszczędnie z usługą 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 otrzymują presję wsteczną z innych usług platformy Azure. W takich przypadkach opóźnienie może pomóc uniknąć ograniczania przepustowości i innych ograniczeń napotykanych przez te usługi. Strategia wycofywania wykładniczego zapewnia większą elastyczność interwałów ponawiania prób i jest często używana podczas integracji z usługami innych firm, punktami końcowymi REST i innymi usługami platformy Azure.

  • Zachowaj niskie interwały i liczba ponownych prób: jeśli to możliwe, spróbuj zachować interwał ponawiania prób krótszy niż minutę. Ponadto należy zachować maksymalną liczbę ponownych 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 błąd błędu przejściowego od czasu do czasu i naturalny przypadek użycia ponownych prób. Jeśli jednak podczas przetwarzania funkcji występuje znaczna liczba awarii lub problemów, warto zatrzymać funkcję, rozwiązać problemy i uruchomić ponownie później.

Ważnym rozwiązaniem zasad ponawiania w usłudze Functions jest to, że jest to najlepsza funkcja ponownego przetwarzania zdarzeń. Nie zastępuje to 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ć, aby zrekompensować problemy, które pojawiają się z powodu awarii lub nieprawidłowych danych w strumieniu zdarzeń. Oto niektóre podstawowe strategie:

  • Przestań wysyłać i odczytywać: aby rozwiązać problem, wstrzymaj odczytywanie i zapisywanie zdarzeń. 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.

  • Usuwanie komunikatów: jeśli komunikaty nie są ważne lub są uznawane za niekrytyczne, rozważ przejście i ich przetwarzanie. Takie podejście nie działa w przypadku scenariuszy 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. Najczęstszym 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: Tutaj chodzi o opublikowanie zdarzenia w innym centrum zdarzeń, aby istniejący przepływ nie został przerwany. Postrzeganie polega na tym, że jest przenoszona poza gorącą ścieżkę i może być traktowana później lub przez inny proces. To rozwiązanie jest często używane do obsługi zatrutych komunikatów lub zdarzeń. Każda funkcja skonfigurowana przy użyciu innej grupy odbiorców nadal będzie napotykać 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 ponownych prób przed ostatecznym opublikowaniem do 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 aktywne narzędzie, aby zwiększyć spójność i jakość danych. Rejestr schematów platformy Azure może obsługiwać przejście schematów wraz z przechowywaniem wersji i różnymi trybami zgodności w miarę rozwoju schematów. Jego rdzeń schemat 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 każdej ze strategii należy dokładnie zbadać. Na podstawie wymagań zastosowanie kilku z tych technik może być najlepszym rozwiązaniem.

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ć niepubalne profile serwisu LinkedIn, zaloguj się do serwisu LinkedIn.

Następne kroki

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

  • Monitorowanie przetwarzania zdarzeń bezserwerowych zawiera wskazówki dotyczące monitorowania architektur opartych na zdarzeniach bezserwerowych.
  • Przetwarzanie zdarzeń bezserwerowych to architektura referencyjna, która szczegółowo opisuje typową architekturę tego typu, z przykładami kodu i omówieniem ważnych zagadnień.