Wzorzec choreografii

Azure Event Grid
Azure Service Bus

Decentralizuj logikę przepływu pracy i dystrybuuj obowiązki innych składników w systemie.

Kontekst i problem

Aplikacja oparta na chmurze jest często podzielona na kilka małych usług, które współpracują ze sobą w celu przetworzenia kompleksowej transakcji biznesowej. Nawet jedna operacja (w ramach transakcji) może spowodować wiele wywołań punkt-punkt między wszystkimi usługami. W idealnym przypadku te usługi powinny być luźno powiązane. Projektowanie przepływu pracy, który jest rozproszony, wydajny i skalowalny, jest trudne, ponieważ często wiąże się ze złożoną komunikacją międzyusługową.

Typowym wzorcem komunikacji jest użycie scentralizowanej usługi lub orkiestratora. Żądania przychodzące przepływają przez koordynatora, ponieważ deleguje operacje do odpowiednich usług. Każda usługa po prostu wypełnia swoją odpowiedzialność i nie jest świadoma ogólnego przepływu pracy.

Diagram przepływu pracy, który przetwarza żądania przy użyciu centralnego orkiestratora.

Wzorzec orkiestratora jest zwykle implementowany jako oprogramowanie niestandardowe i ma wiedzę o domenie na temat obowiązków tych usług. Zaletą jest to, że orkiestrator może skonsolidować stan transakcji na podstawie wyników poszczególnych operacji wykonywanych przez usługi podrzędne.

Istnieją jednak pewne wady. Dodawanie lub usuwanie usług może spowodować przerwanie istniejącej logiki, ponieważ konieczne jest ponowne połączenie części ścieżki komunikacyjnej. Ta zależność sprawia, że implementacja orkiestratora jest złożona i trudna do utrzymania. Orkiestrator może mieć negatywny wpływ na niezawodność obciążenia. Obciążenie może powodować wąskie gardło wydajności i być pojedynczym punktem awarii. Może również powodować błędy kaskadowe w usługach podrzędnych.

Rozwiązanie

Deleguj logikę obsługi transakcji między usługami. Pozwól każdej usłudze decydować i uczestniczyć w przepływie pracy komunikacji dla operacji biznesowej.

Wzorzec jest sposobem zminimalizowania zależności od oprogramowania niestandardowego, które centralizuje przepływ pracy komunikacji. Składniki implementują wspólną logikę, ponieważ choreografują przepływ pracy między sobą bez bezpośredniej komunikacji ze sobą.

Typowym sposobem implementacji choreografii jest użycie brokera komunikatów, który buforuje żądania do momentu, gdy składniki podrzędne oświadczeń i przetwarzają je. Obraz przedstawia obsługę żądań za pośrednictwem modelu wydawcy-subskrybenta.

Diagram przedstawiający przetwarzanie żądania przy użyciu brokera komunikatów.

  1. Żądania klienta są kolejkowane jako komunikaty w brokerze komunikatów.

  2. Usługi lub subskrybent sondują brokera, aby określić, czy mogą przetwarzać ten komunikat na podstawie wdrożonej logiki biznesowej. Broker może również wypychać komunikaty do subskrybentów, którzy są zainteresowani tą wiadomością.

  3. Każda subskrybowana usługa wykonuje operację wskazaną przez komunikat i reaguje na brokera z powodzeniem lub niepowodzeniem operacji.

  4. W przypadku powodzenia usługa może wypchnąć komunikat z powrotem do tej samej kolejki lub innej kolejki komunikatów, aby inna usługa mogła kontynuować przepływ pracy w razie potrzeby. Jeśli operacja zakończy się niepowodzeniem, broker komunikatów współpracuje z innymi usługami, aby zrekompensować tę operację lub całą transakcję.

Problemy i kwestie do rozważenia

Decentralizacja orkiestratora może powodować problemy podczas zarządzania przepływem pracy.

  • Błędy przekazywania mogą być trudne. Składniki w aplikacji mogą wykonywać niepodzielne zadania, ale nadal mogą mieć poziom zależności. Awaria w jednym składniku może mieć wpływ na inne, co może spowodować opóźnienia w zakończeniu ogólnego żądania.

    Aby bezpiecznie obsługiwać błędy, implementacja transakcji wyrównywujących może spowodować złożoność. Logika obsługi błędów, taka jak transakcje wyrównujące, również jest podatna na błędy.

    Schemat blokowy przedstawiający obsługę błędów we wzorcu choreografii.

  • Wzorzec jest odpowiedni dla przepływu pracy, w którym niezależne operacje biznesowe są przetwarzane równolegle. Przepływ pracy może stać się skomplikowany, gdy choreografia musi wystąpić w sekwencji. Na przykład usługa D może uruchomić swoją operację dopiero po zakończeniu operacji przez usługę B i usługę C.

    Diagram przepływu pracy w systemie obsługi komunikatów, który implementuje wzorzec choreografii równolegle, a następnie.

  • Wzorzec staje się wyzwaniem, jeśli liczba usług szybko rośnie. Biorąc pod uwagę dużą liczbę niezależnych części ruchomych, przepływ pracy między usługami zwykle staje się złożony. Ponadto śledzenie rozproszone staje się trudne, chociaż narzędzia takie jak ServiceInsight wraz z NServiceBus mogą pomóc zmniejszyć te wyzwania.

  • W projekcie kierowanym przez koordynatora składnik centralny może częściowo uczestniczyć i delegować logikę odporności do innego składnika, który ponawia próby przejściowe, nieprzejrzyste i błędy przekroczenia limitu czasu, spójnie. Dzięki rozwiązaniu orkiestratora we wzorcu choreografii składniki podrzędne nie powinny pobierać tych zadań odporności. Muszą one być nadal obsługiwane przez program obsługi odporności. Jednak teraz składniki podrzędne muszą bezpośrednio komunikować się z procedurą obsługi odporności, zwiększając komunikację punkt-punkt.

Kiedy używać tego wzorca

Użyj tego wzorca, gdy:

  • Składniki podrzędne obsługują operacje niepodzielne niezależnie. Pomyśl o tym jako o mechanizmie "ognia i zapomnienia". Składnik jest odpowiedzialny za zadanie, które nie musi być aktywnie zarządzane. Po zakończeniu zadania wysyła ono powiadomienie do innych składników.

  • Oczekuje się, że składniki będą aktualizowane i często zastępowane. Wzorzec umożliwia modyfikację aplikacji z mniejszym nakładem pracy i minimalnymi zakłóceniami w istniejących usługach.

  • Wzorzec jest naturalnym rozwiązaniem dla architektur bezserwerowych, które są odpowiednie dla prostych przepływów pracy. Składniki mogą być krótkotrwałe i sterowane zdarzeniami. Gdy wystąpi zdarzenie, składniki są spun up, wykonują swoje zadania i usuwane po zakończeniu zadania.

  • Ten wzorzec może być dobrym wyborem dla komunikacji między powiązanymi kontekstami. W przypadku komunikacji wewnątrz pojedynczego ograniczonego kontekstu można rozważyć wzorzec orkiestratora.

  • Występuje wąskie gardło wydajności wprowadzone przez centralnego koordynatora.

Ten wzorzec może nie być przydatny w następujących sytuacjach:

  • Aplikacja jest złożona i wymaga centralnego składnika do obsługi logiki udostępnionej, aby zachować lekkie składniki podrzędne.

  • Istnieją sytuacje, w których komunikacja punkt-punkt między składnikami jest nieunikniona.

  • Należy skonsolidować wszystkie operacje obsługiwane przez składniki podrzędne przy użyciu logiki biznesowej.

Projekt obciążenia

Architekt powinien ocenić, w jaki sposób wzorzec choreografii 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
Doskonałość operacyjna pomaga zapewnić jakość obciążeń dzięki ustandaryzowanym procesom i spójności zespołu. Ponieważ składniki rozproszone w tym wzorcu są autonomiczne i zaprojektowane tak, aby można je było zamienić, można zmodyfikować obciążenie przy użyciu mniej ogólnej zmiany w systemie.

- OE:04 Narzędzia i procesy
Wydajność pomaga wydajnie sprostać zapotrzebowaniu dzięki optymalizacjom skalowania, danych, kodu. Ten wzorzec stanowi alternatywę, gdy wąskie gardła wydajności występują w scentralizowanej topologii aranżacji.

- PE:02 Planowanie pojemności
- 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

W tym przykładzie pokazano wzorzec choreografii przez utworzenie opartego na zdarzeniach obciążenia natywnego dla chmury z uruchomionymi funkcjami wraz z mikrousługami. Gdy klient żąda wysłania pakietu, obciążenie przypisuje drona. Gdy pakiet będzie gotowy do odbioru przez zaplanowanego drona, rozpocznie się proces dostarczania. Podczas przesyłania obciążenia obsługuje dostawę do momentu uzyskania stanu wysyłki.

W tym przykładzie jest refaktoryzacja implementacji Drone Delivery, która zastępuje wzorzec orkiestratora wzorcem choreografii.

Diagram przykładowego obciążenia implementowania choreografii opartej na zdarzeniach opartych na chmurze

Usługa pozyskiwania obsługuje żądania klientów i konwertuje je na komunikaty, w tym szczegóły dostarczania. Transakcje biznesowe są inicjowane po użyciu tych nowych komunikatów.

Jedna transakcja biznesowa klienta wymaga trzech odrębnych operacji biznesowych:

  1. Tworzenie lub aktualizowanie pakietu
  2. Przypisywanie drona w celu dostarczenia pakietu
  3. Obsługa dostawy, która składa się z sprawdzania i ostatecznie podnoszenia świadomości po wysłaniu.

Trzy mikrousługi wykonują przetwarzanie biznesowe: Pakiet, Harmonogram dronów i Usługi dostarczania. Zamiast centralnego orkiestratora usługi używają komunikatów do komunikowania się między sobą. Każda usługa będzie odpowiedzialna za zaimplementowanie protokołu z wyprzedzeniem, który koordynuje się w zdecentralizowany sposób przepływu pracy biznesowego.

Projektowanie

Transakcja biznesowa jest przetwarzana w sekwencji za pośrednictwem wielu przeskoków. Każdy przeskok udostępnia jedną magistralę komunikatów wśród wszystkich usług biznesowych.

Gdy klient wysyła żądanie dostawy za pośrednictwem punktu końcowego HTTP, usługa pozyskiwania odbiera je, konwertuje takie żądanie na komunikat, a następnie publikuje komunikat do udostępnionej magistrali komunikatów. Subskrybowane usługi biznesowe będą korzystać z nowych komunikatów dodanych do magistrali. Po otrzymaniu komunikatu usługi biznesowe mogą ukończyć operację z powodzeniem, niepowodzeniem lub żądanie może upłynął limit czasu. W przypadku powodzenia usługi odpowiadają na magistralę przy użyciu kodu stanu OK, zgłasza nowy komunikat operacji i wysyła go do magistrali komunikatów. Jeśli wystąpi błąd lub przekroczenie limitu czasu, usługa zgłasza błąd, wysyłając kod przyczyny do magistrali komunikatów. Ponadto komunikat jest dodawany do kolejki utraconych komunikatów. Komunikaty, których nie można odebrać lub przetworzyć w rozsądnym i odpowiednim czasie, są również przenoszone dlQ.

Projekt używa wielu magistrali komunikatów do przetwarzania całej transakcji biznesowej. Usługi Microsoft Azure Service Bus i Microsoft Azure Event Grid składają się w celu zapewnienia platformy usługi obsługi komunikatów dla tego projektu. Obciążenie jest wdrażane w usłudze Azure Container Apps hostujące usługę Azure Functions na potrzeby pozyskiwania i aplikacji obsługujących przetwarzanie sterowane zdarzeniami , które wykonuje logikę biznesową.

Projekt gwarantuje, że choreografia będzie występować w sekwencji. Pojedyncza przestrzeń nazw usługi Azure Service Bus zawiera temat z dwiema subskrypcjami i kolejką z obsługą sesji. Usługa pozyskiwania publikuje komunikaty w temacie. Usługa Package service i Drone Scheduler subskrybują temat i publikują komunikaty informujące o powodzeniu kolejki. Dołączenie wspólnego identyfikatora sesji, który identyfikator GUID skojarzony z identyfikatorem dostarczania umożliwia uporządkowaną obsługę niezwiązanych sekwencji powiązanych komunikatów. Usługa dostarczania oczekuje dwóch powiązanych komunikatów na transakcję. Pierwszy komunikat wskazuje, że pakiet jest gotowy do wysłania, a drugi sygnały, że dron jest zaplanowany.

Ten projekt używa usługi Azure Service Bus do obsługi komunikatów o wysokiej wartości, których nie można utracić ani duplikować podczas całego procesu dostarczania. Po wysłaniu pakietu zostanie również opublikowana zmiana stanu na usługę Azure Event Grid. W tym projekcie nadawca zdarzeń nie ma oczekiwań co do sposobu obsługi zmiany stanu. Usługi podrzędne organizacji, które nie są uwzględnione w ramach tego projektu, mogą nasłuchiwać tego typu zdarzenia i reagować na wykonywanie określonej logiki celu biznesowego (czyli wysłać wiadomość e-mail ze stanem wysłanego zamówienia do użytkownika).

Jeśli planujesz wdrożyć tę funkcję w innej usłudze obliczeniowej, takiej jak aks pub-sub pattern application boilerplate, można zaimplementować z dwoma kontenerami w tym samym zasobniku. Jeden kontener uruchamia ambasadora , który współdziała z magistralą komunikatów preferencji, podczas gdy drugi wykonuje logikę biznesową. Podejście z dwoma kontenerami w tym samym zasobniku zwiększa wydajność i skalowalność. Ambasador i usługa biznesowa korzystają z tej samej sieci, co pozwala na małe opóźnienia i wysoką przepływność.

Aby uniknąć kaskadowych operacji ponawiania, które mogą prowadzić do wielu wysiłków, usługi biznesowe powinny natychmiast oznaczać niedopuszczalne komunikaty. Istnieje możliwość wzbogacenia takich komunikatów przy użyciu dobrze znanych kodów przyczyn lub zdefiniowanego kodu aplikacji, aby można je było przenieść do kolejki utraconych listów (DLQ). Rozważ zarządzanie problemami ze spójnością, które implementuje saga z usług podrzędnych. Na przykład inna usługa może obsługiwać komunikaty z komunikatami utraconymi w celach korygujących tylko przez wykonanie rekompensaty, ponawiania próby lub przestawienia transakcji.

Usługi biznesowe są idempotentne, aby upewnić się, że operacje ponawiania nie powodują zduplikowania zasobów. Na przykład usługa Package używa operacji upsert do dodawania danych do magazynu danych.

Weź pod uwagę te wzorce w projekcie choreografii.