Udostępnij za pośrednictwem


Styl architektury sterowanej zdarzeniami

Azure Stream Analytics
Azure Functions
Azure Service Bus

Architektura sterowana zdarzeniami składa się z producentów zdarzeń, którzy generują strumień zdarzeń, odbiorców zdarzeń, którzy nasłuchują tych zdarzeń, oraz kanałów zdarzeń, które przesyłają zdarzenia od producentów do konsumentów.

Diagram przedstawiający styl architektury sterowanej zdarzeniami.

Zdarzenia są dostarczane prawie w czasie rzeczywistym, więc odbiorcy mogą natychmiast na nie reagować w momencie ich wystąpienia. Producenci są oddzieleni od konsumentów: producent nie wie, którzy konsumenci słuchają. Odbiorcy są również całkowicie niezależni od siebie nawzajem, a każdy odbiorca widzi wszystkie zdarzenia. Ten proces różni się od wzorca konkurujących odbiorców , w którym konsumenci ściągają komunikaty z kolejki, a komunikat jest przetwarzany tylko raz, przy założeniu, że nie ma żadnych błędów. W niektórych systemach, takich jak Azure Internet of Things (IoT), zdarzenia muszą być pozyskiwane na dużych ilościach.

Architektura sterowana zdarzeniami może używać modelu publikowania-subskrybowania lub modelu strumienia zdarzeń.

  • Pub/sub: Infrastruktura komunikatów publikuj-subskrybuj śledzi subskrypcje. Gdy zostaje opublikowane zdarzenie, wysyła zdarzenie do wszystkich subskrybentów. Nie można odtworzyć zdarzenia po jego odebraniu, a nowi subskrybenci nie widzą zdarzenia.

  • Przesyłanie strumieniowe zdarzeń: Zdarzenia są zapisywane w dzienniku. Zdarzenia są ściśle uporządkowane w ramach partycji i są trwałe. Klienci nie subskrybują strumienia. Zamiast tego klient może odczytywać z dowolnej części strumienia. Klient jest odpowiedzialny za rozwijanie pozycji w strumieniu. Oznacza to, że klient może dołączyć w dowolnym momencie i może odtwarzać zdarzenia.

Po stronie odbiorcy znajduje się parę typowych odmian:

  • Proste przetwarzanie zdarzeń: Zdarzenie natychmiast wyzwala akcję w odbiorcy. Możesz na przykład użyć usługi Azure Functions z wyzwalaczem usługi Azure Service Bus, aby funkcja działała za każdym razem, gdy komunikat zostanie opublikowany w temacie usługi Service Bus.

  • Podstawowa korelacja zdarzeń: Użytkownik przetwarza kilka odrębnych zdarzeń biznesowych, koreluje je według określonego identyfikatora i utrwala informacje z wcześniejszych zdarzeń do użycia podczas przetwarzania późniejszych zdarzeń. Biblioteki takie jak NServiceBus i MassTransit obsługują ten wzorzec.

  • Złożone przetwarzanie zdarzeń: Użytkownik korzysta z technologii takiej jak Usługa Azure Stream Analytics do analizowania serii zdarzeń i identyfikowania wzorców w danych zdarzenia. Można na przykład agregować odczyty z urządzenia osadzonego w przedziale czasu i wygenerować powiadomienie, jeśli średnia ruchoma przekroczy określony próg.

  • Przetwarzanie strumienia zdarzeń: Użyj platformy przesyłania strumieniowego danych, takiej jak Azure IoT Hub lub Apache Kafka, jako potoku do pozyskiwania zdarzeń i przesyłania ich do procesorów strumieniowych. Procesory strumieni przetwarzają lub przekształcają strumień. Może istnieć wiele procesorów strumienia dla różnych podsystemów aplikacji. Ta metoda jest odpowiednia dla obciążeń IoT.

Źródło zdarzeń może być zewnętrzne dla systemu, takie jak urządzenia fizyczne w rozwiązaniu IoT. W takim przypadku system musi mieć możliwość pozyskiwania danych na woluminie i przepływności wymaganej przez źródło danych.

Istnieją dwa podstawowe podejścia do struktury ładunków zdarzeń. Gdy masz kontrolę nad użytkownikami zdarzeń, możesz zdecydować o strukturze ładunku dla każdego odbiorcy. Ta strategia umożliwia mieszanie podejść zgodnie z potrzebami w ramach pojedynczego obciążenia.

  • Uwzględnij wszystkie wymagane atrybuty w ładunku: Użyj tej metody, jeśli chcesz, aby użytkownicy mieli wszystkie dostępne informacje bez konieczności wykonywania zapytań względem zewnętrznego źródła danych. Jednak może to prowadzić do problemów ze spójnością danych z powodu wielu systemów rekordów, szczególnie po aktualizacjach. Zarządzanie umowami i przechowywanie wersji mogą również stać się złożone.

  • Uwzględnij tylko klucze w ładunku: W tym podejściu konsumenci pobierają niezbędne atrybuty, takie jak klucz podstawowy, aby niezależnie pobierać pozostałe dane ze źródła danych. Ta metoda zapewnia lepszą spójność danych, ponieważ ma jeden system rekordów. Może jednak działać źle niż pierwsze podejście, ponieważ konsumenci muszą często wykonywać zapytania dotyczące źródła danych. Masz mniej problemów dotyczących sprzęgania, przepustowości, zarządzania kontraktami lub przechowywania wersji, ponieważ mniejsze zdarzenia i prostsze kontrakty zmniejszają złożoność.

Na powyższym diagramie każdy typ konsumenta jest wyświetlany jako pojedyncze pole. Aby uniknąć, aby konsument stał się pojedynczym punktem awarii w systemie, zwykle ma wiele wystąpień konsumenta. Wiele wystąpień może być również wymaganych do obsługi woluminu i częstotliwości zdarzeń. Pojedynczy odbiorca może przetwarzać zdarzenia w wielu wątkach. Ta konfiguracja może stanowić wyzwanie, jeśli zdarzenia muszą być przetwarzane w kolejności lub wymagają dokładnie raz semantyki. Aby uzyskać więcej informacji, zobacz Minimalizuj koordynację.

Istnieją dwie główne topologie w wielu architekturach opartych na zdarzeniach:

  • Topologia brokera: Składniki emitować wystąpienia jako zdarzenia do całego systemu. Inne składniki działają na zdarzeniu lub ignorują zdarzenie. Ta topologia jest przydatna, gdy przepływ przetwarzania zdarzeń jest stosunkowo prosty. Nie ma centralnej koordynacji ani aranżacji, więc ta topologia może być dynamiczna. Ta topologia jest wysoce oddzielona, co pomaga zapewnić skalowalność, czas odpowiedzi i odporność na uszkodzenia składników. Żaden składnik nie jest właścicielem ani nie zna stanu każdej wieloetapowej transakcji biznesowej, a akcje są wykonywane asynchronicznie. Następnie transakcje rozproszone są ryzykowne, ponieważ nie ma natywnego sposobu ponownego uruchamiania ani odtwarzania. Należy dokładnie rozważyć obsługę błędów i strategie interwencji ręcznej, ponieważ ta topologia może być źródłem niespójności danych.

  • Topologia mediatora: Ta topologia dotyczy niektórych niedociągnięć topologii brokera. Istnieje mediator wydarzenia, który zarządza przepływem wydarzeń i kontroluje go. Mediator zdarzeń utrzymuje stan i zarządza możliwościami obsługi błędów i ponownego uruchamiania. W przeciwieństwie do topologii brokera, w tej topologii składniki emitować wystąpienia jako polecenia i tylko do wyznaczonych kanałów. Te kanały to zazwyczaj kolejki komunikatów. Oczekuje się, że konsumenci będą przetwarzać te polecenia. Ta topologia zapewnia większą kontrolę, lepszą rozproszoną obsługę błędów i potencjalnie lepszą spójność danych. Ta topologia wprowadza zwiększone sprzężenie między składnikami, a mediator zdarzeń może stać się wąskim gardłem lub problemem dotyczącym niezawodności.

Kiedy stosować tę architekturę

Należy użyć tej architektury, gdy:

  • Wiele podsystemów musi przetwarzać te same zdarzenia.
  • Przetwarzanie w czasie rzeczywistym z minimalnym opóźnieniem czasu jest wymagane.
  • Wymagane jest złożone przetwarzanie zdarzeń, takie jak dopasowywanie wzorców lub agregacja w oknach czasu.
  • Wymagana jest duża ilość i wysoka szybkość danych, tak jak na przykład IoT.

Świadczenia

Zalety tej architektury to:

  • Producenci i odbiorcy są całkowicie niezależni.
  • Brak integracji punkt-punkt. Łatwo dodawać nowych odbiorców do systemu.
  • Użytkownicy mogą natychmiast reagować na zdarzenia w miarę ich występowania.
  • Wysoce skalowalne, elastyczne i rozproszone.
  • Podsystemy mają niezależne widoki strumienia zdarzeń.

Wyzwania

  • Gwarancja dostarczenia.

    W niektórych systemach, szczególnie w scenariuszach IoT, jest niezwykle istotne, aby zagwarantować dostarczenie zdarzeń.

  • Przetwarzanie zdarzeń w kolejności lub dokładnie jednokrotnie.

    W celu zapewnienia odporności i skalowalności każdy typ konsumenta zazwyczaj działa w wielu wystąpieniach. Ten proces może stanowić wyzwanie, jeśli zdarzenia muszą być przetwarzane w kolejności w ramach typu odbiorcy lub jeśli logika przetwarzania komunikatów idempotentnych nie jest zaimplementowana.

  • Koordynacja komunikatów między usługami.

    Procesy biznesowe często mają wiele usług, które publikują i subskrybują komunikaty, aby osiągnąć spójny wynik w całym obciążeniu. Wzorce przepływu pracy , takie jak wzorzec choreografii i orkiestracja Saga , umożliwiają niezawodne zarządzanie przepływami komunikatów w różnych usługach.

  • Obsługa błędów.

    Architektura sterowana zdarzeniami używa głównie komunikacji asynchronicznej. Wyzwanie związane z asynchroniczną komunikacją polega na obsłudze błędów. Jednym ze sposobów rozwiązania tego problemu jest użycie oddzielnego procesora obsługi błędów. Gdy użytkownik zdarzenia napotyka błąd, natychmiast i asynchronicznie wysyła błędne zdarzenie do procesora obsługi błędów i przechodzi dalej. Procesor obsługi błędów próbuje naprawić błąd i wysyła zdarzenie z powrotem do oryginalnego kanału pozyskiwania. Jeśli jednak procesor obsługi błędów ulegnie awarii, może wysłać błędne zdarzenie do administratora w celu dalszej inspekcji. Jeśli używasz procesora obsługi błędów, błędne zdarzenia są przetwarzane poza sekwencją po ich ponownym wysłaniu.

  • Utrata danych.

    Innym wyzwaniem z asynchroniczną komunikacją jest utrata danych. Jeśli którykolwiek ze składników ulegnie awarii przed pomyślnym przetworzeniem i przekazaniem zdarzenia do następnego składnika, zdarzenie zostanie porzucone i nigdy nie przejdzie do końcowego miejsca docelowego. Aby zminimalizować ryzyko utraty danych, utrwal zdarzenia podczas przesyłania i usuń lub usuń zdarzenia w kolejce tylko wtedy, gdy następny składnik potwierdzi otrzymanie zdarzenia. Te funkcje są znane jako tryb potwierdzenia klienta i ostatnia obsługa uczestnika.

  • Implementacja tradycyjnego wzorca żądania-odpowiedzi.

    Czasami producent zdarzeń wymaga natychmiastowej odpowiedzi od odbiorcy zdarzeń, takiego jak uzyskanie uprawnień klienta przed kontynuowaniem zamówienia. W architekturze sterowanej zdarzeniami komunikacja synchroniczna można osiągnąć za pomocą komunikatów żądań odpowiedzi.

    Ten wzorzec jest zwykle implementowany przy użyciu dwóch kolejek: kolejki żądań i kolejki odpowiedzi. Producent zdarzeń wysyła żądanie asynchroniczne do kolejki żądań, wstrzymuje inne operacje w tym zadaniu i oczekuje na odpowiedź w kolejce odpowiedzi. Takie podejście skutecznie przekształca ten wzorzec w proces synchroniczny. Następnie odbiorcy zdarzeń przetwarzają żądanie i wysyłają odpowiedź z powrotem za pośrednictwem kolejki odpowiedzi. Takie podejście zwykle używa identyfikatora sesji do śledzenia, więc producent zdarzeń wie, który komunikat w kolejce odpowiedzi jest powiązany z określonym żądaniem. Oryginalne żądanie może również określać nazwę kolejki odpowiedzi, potencjalnie efemerycznej, w nagłówku odpowiedzi lub inny wzajemnie uzgodniony atrybut niestandardowy.

  • Konserwacja odpowiedniej liczby zdarzeń.

    Generowanie nadmiernej liczby drobnych zdarzeń może saturacji i przeciążenia systemu, co utrudnia efektywne analizowanie ogólnego przepływu zdarzeń. Ten problem jest zaostrzony, gdy zmiany muszą zostać wycofane. Z drugiej strony zbyt skonsolidowanie zdarzeń może również powodować problemy, co powoduje niepotrzebne przetwarzanie i odpowiedzi od użytkowników zdarzeń.

    Aby osiągnąć właściwą równowagę, należy wziąć pod uwagę konsekwencje zdarzeń i to, czy konsumenci muszą sprawdzić ładunki zdarzeń, aby określić ich odpowiedzi. Na przykład jeśli masz składnik sprawdzania zgodności, może być wystarczająca do opublikowania tylko dwóch typów zdarzeń: zgodnych i niezgodnych. Takie podejście pomaga zapewnić, że tylko odpowiedni konsumenci przetwarzają każde zdarzenie, co zapobiega niepotrzebnemu przetwarzaniu.

Inne uwagi

  • Ilość danych, które należy uwzględnić w zdarzeniu, może być istotnym czynnikiem wpływającym zarówno na wydajność, jak i koszt. Możesz uprościć przetwarzanie kodu i wyeliminować dodatkowe wyszukiwania, umieszczając wszystkie istotne informacje potrzebne do przetwarzania bezpośrednio w zdarzeniu. W przypadku dodawania tylko minimalnej ilości informacji do zdarzenia, takiego jak kilka identyfikatorów, można skrócić czas transportu i koszt. Jednak takie podejście wymaga kodu przetwarzania w celu pobrania wszelkich dodatkowych informacji, których potrzebuje. Aby uzyskać więcej informacji, zobacz Wprowadzenie wydarzeń na dietę.

  • Żądanie jest widoczne tylko dla składnika obsługi żądań. Jednak zdarzenia są często widoczne dla wielu składników w obciążeniu, nawet jeśli te składniki nie są przeznaczone do ich użycia. Aby pracować z myślą o "założeniu naruszenia", należy pamiętać o informacjach uwzględnionych w zdarzeniach, aby zapobiec niezamierzonej ekspozycji na informacje.

  • Wiele aplikacji używa architektury opartej na zdarzeniach jako podstawowej architektury. To podejście można połączyć z innymi stylami architektury, aby utworzyć architekturę hybrydową. Typowe kombinacje obejmują mikrousługi i potoki i filtry. Zintegruj architekturę sterowaną zdarzeniami, aby zwiększyć wydajność systemu, eliminując wąskie gardła i zapewniając ciśnienie wsteczne podczas dużych ilości żądań.

  • Określone domeny często obejmują wielu producentów zdarzeń, odbiorców lub kanałów zdarzeń. Zmiany w określonej domenie mogą mieć wpływ na wiele składników.

  • Wideo dyskusyjne społeczności dotyczące zagadnień dotyczących wyboru między choreografią a orkiestracją.