Notatka
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Pozwól każdej usłudze decydować, kiedy i jak przetwarzać operację biznesową, zamiast polegać na centralnym orkiestratorze. Takie podejście decentralizuje logikę przepływu pracy i dystrybuuje obowiązki między składniki systemu.
Kontekst i problem
Zazwyczaj aplikacja oparta na chmurze jest podzielona na kilka małych usług, które współpracują ze sobą w celu przetworzenia kompleksowej transakcji biznesowej. Pojedyncza operacja w ramach transakcji może spowodować wiele połączeń punkt-do-punktu pomiędzy wszystkimi usługami. W idealnym przypadku te usługi są luźno powiązane. Projektowanie rozproszonego, wydajnego i skalowalnego przepływu pracy jest trudne, ponieważ obejmuje 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, gdy deleguje operacje do odpowiednich usług. Każda usługa wykonuje swoją odpowiedzialność i nie jest świadoma ogólnego przepływu pracy.
Wzorzec orkiestratora zazwyczaj implementuje się jako oprogramowanie dostosowane do potrzeb, które ma wiedzę na temat ról i obowiązków usług w systemie. Jedną z zalet tego podejścia jest to, że orkiestrator może skonsolidować stan transakcji na podstawie wyników poszczególnych operacji wykonywanych przez usługi podrzędne.
Takie podejście stwarza również pewne przeszkody. 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 negatywnie wpłynąć na niezawodność obciążenia. Obciążenie może powodować wąskie gardła wydajności i być pojedynczym punktem awarii (SPoF). Gdy orkiestrator ulegnie awarii lub stanie się przeciążony, awaria może być propagowana do wszystkich zależnych usług podrzędnych.
Rozwiązanie
Deleguj logikę obsługi transakcji między usługami. Pozwól każdej usłudze uczestniczyć w procesie komunikacyjnym w operacji biznesowej i decydować, kiedy oraz jak przetwarzać ten proces.
Wzorzec choreografii minimalizuje zależność od niestandardowego oprogramowania, 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 komponenty podrzędne przyjmują je i przetwarzają. Na poniższej ilustracji przedstawiono obsługę żądań za pomocą modelu wydawcy-subskrybenta.
Żądania klienta są umieszczane w kolejce jako komunikaty w brokerze wiadomości.
Usługi lub subskrybent sprawdza u brokera, czy na podstawie wdrożonej logiki biznesowej może przetworzyć komunikat. Broker może również wypychać komunikaty do subskrybentów zainteresowanych tą wiadomością.
Każda subskrybowana usługa wykonuje swoją operację zgodnie z instrukcją zawartą w komunikacie i odpowiada brokerowi komunikatem o powodzeniu lub niepowodzeniu operacji.
Jeśli operacja zakończy się pomyślnie, usługa może opublikować komunikat w tej samej kolejce lub w innej kolejce komunikatów, aby inna usługa mogła w razie potrzeby kontynuować przepływ pracy. Jeśli operacja zakończy się niepowodzeniem, usługa publikuje komunikat o błędzie. Usługi subskrybujące ten komunikat mogą uruchamiać wstępnie zdefiniowane akcje kompensacyjne dla nieudanej operacji lub całej transakcji.
Problemy i zagadnienia
Podczas podejmowania decyzji o sposobie implementacji tego wzorca należy wziąć pod uwagę następujące kwestie:
Złożoność obsługi błędów. Składniki w aplikacji mogą zarządzać zadaniami atomowymi i zależeć od innych części systemu. Awaria w jednym składniku może mieć wpływ na inne składniki, co może spowodować opóźnienia w zakończeniu ogólnego żądania.
Aby bezpiecznie obsługiwać błędy, należy zaimplementować logikę obsługi błędów, która wprowadza złożoność. Logika obsługi błędów, taka jak transakcje wyrównujące, również jest podatna na błędy.
Sekwencyjne procesy. Ten wzorzec odpowiada przepływowi pracy, który równolegle przetwarza niezależne operacje biznesowe. Przepływ pracy może stać się skomplikowany, gdy choreografia musi wystąpić w sekwencji. Na przykład usługa D może uruchomić operację dopiero po pomyślnym zakończeniu operacji przez usługę B i usługę C.
Możliwość obserwowania na dużą skalę. Ten wzorzec stwarza wyzwania, jeśli liczba usług szybko rośnie. Wiele niezależnych ruchomych części komplikuje przepływ pracy między usługami. Bez centralnego koordynatora utrzymującego pełny stan transakcji żaden pojedynczy komponent nie ma pełnego obrazu trwającej operacji biznesowej. Aby zachować widoczność, należy stale używać rozproszonego śledzenia i identyfikatorów korelacji.
Komunikacja modułu obsługi odporności na awarie. W architekturze zarządzanej przez orkiestrator komponent centralny może delegować zadania związane z zapewnianiem odporności, takie jak obsługa ponowień w przypadku błędów przejściowych, nieprzejściowych i przekroczenia limitu czasu, do dedykowanego modułu odporności.
Po usunięciu orkiestratora w projekcie opartym na choreografii składniki podrzędne nie przyjmują obowiązków związanych z odpornością. Pozostają one scentralizowane w programie obsługi odporności. Jednak składniki podrzędne muszą komunikować się bezpośrednio z tym programem obsługi, co zwiększa komunikację punkt-punkt.
Ewolucja schematu zdarzeń. Ewolucja schematu zdarzeń może powodować zmiany powodujące niezgodność po stronie konsumentów w czasie. W tym wzorcu wiele niezależnych usług korzysta z tych samych zdarzeń. Jeśli producent zmieni strukturę danych zdarzenia, może przerwać odbiorców podrzędnych, którzy zależą od starego schematu. Użyj rejestru schematów do zarządzania kontraktami zdarzeń i stosuj ewolucję zgodną wstecz, gdy usługi ewoluują niezależnie.
Idempotentność i kolejność zdarzeń. Co najmniej jednokrotne dostarczanie i ponawianie prób może generować zduplikowane komunikaty, a współbieżni odbiorcy mogą przetwarzać komunikaty poza kolejnością. Projektuj konsumentów tak, aby byli idempotentni, poprzez śledzenie stałych identyfikatorów komunikatów. Gdy przetwarzanie uporządkowane jest wymagane, należy użyć funkcji brokera, takich jak sesje Service Bus lub uwzględnić dane sekwencji lub wersji, które umożliwiają konsumentom odrzucanie nieaktualnych zdarzeń i wykrywanie luk.
Publikacja stanu atomowego i zdarzeń. Usługa, która aktualizuje repozytorium danych i publikuje zdarzenie w osobnych operacjach, może zatwierdzić jedną operację, podczas gdy druga się nie powiedzie. Użyj wzorca Transactional Outbox lub równoważnego mechanizmu atomowego, aby utrwalić jednocześnie zmianę stanu i zdarzenie, zanim zdarzenie zostanie opublikowane przez oddzielny proces.
Zachowania emergentne i nawałnice zdarzeń. Zdecentralizowane topologie zdarzeń mogą tworzyć pojawiające się zachowania na dużą skalę. Gdy wiele usług reaguje na swoje wzajemne zdarzenia, system może przypadkowo tworzyć pętle sprzężenia zwrotnego lub burze zdarzeń. Drobne zdarzenie może wywołać kaskadę reakcji następujących. Aby zapobiec łańcuchom zdarzeń cyklicznych, należy używać barier zabezpieczających, takich jak filtrowanie zdarzeń, limity współbieżności konsumentów, ograniczanie przepustowości i jawne reguły.
Kiedy należy używać tego wzorca
Użyj tego wzorca, gdy:
Komponenty podrzędne obsługują operacje atomowe niezależnie od siebie w modelu fire and forget. Każdy komponent wykonuje zadanie, a następnie sygnalizuje innym komponentom jego ukończenie za pośrednictwem brokera komunikatów. Usługa inicjująca nie zarządza ani nie śledzi zadania po jego wysłaniu, ale usługi podrzędne nadal komunikują wyniki za pośrednictwem zdarzeń.
Oczekujesz, że składniki będą często aktualizowane i zastępowane. Ten wzorzec umożliwia modyfikowanie aplikacji z mniejszym nakładem pracy i minimalnymi zakłóceniami w istniejących usługach.
Architektury bezserwerowe są używane do prostych przepływów pracy. Składniki mogą być krótkoczasowe i sterowane zdarzeniami. Gdy wystąpi zdarzenie, usługa tworzy składniki, które wykonują zadanie, a usługa usuwa składniki po zakończeniu tego zadania.
Komunikacja między powiązanymi kontekstami wymaga luźnego sprzężenia między granicami domeny. W przypadku komunikacji wewnątrz jednego ograniczonego kontekstu rozważ zamiast tego wzorzec orkiestratora, w zależności od złożoności i preferencji zespołu.
Centralny koordynator wprowadza wąskie gardło wydajności.
Ten wzorzec może nie być odpowiedni w następujących przypadkach:
Aplikacja jest złożona i wymaga centralnego składnika do obsługi logiki udostępnionej, aby zachować lekkie składniki podrzędne.
Komunikacja punkt-punkt między składnikami jest nieunikniona.
Aby skonsolidować wszystkie operacje obsługiwane przez składniki podrzędne, należy użyć logiki biznesowej.
Projektowanie obciążeń roboczych
Oceń, jak używać wzorca choreografii w projektowaniu obciążenia, odpowiadając na cele i zasady opisane w filarach platformy Azure Well-Architected Framework. Poniższa tabela zawiera wskazówki dotyczące tego, jak ten wzorzec obsługuje cele poszczególnych filarów.
| 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. | Składniki rozproszone w tym wzorcu są autonomiczne i zaprojektowane tak, aby można je było zastąpić, dzięki czemu można modyfikować obciążenie przy użyciu mniej ogólnej zmiany w systemie. - OE:04 Narzędzia i procesy |
| Efektywność wydajności pomaga wydajnie sprostać wymaganiom dzięki optymalizacjom skalowania, danych i kodu. | Ten wzorzec oferuje alternatywę, gdy w scentralizowanej topologii orkiestracji występują wąskie gardła wydajności. - 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 obciążenia natywnego dla chmury opartego na zdarzeniach, które uruchamia funkcje wraz z mikrousługami. Gdy klient żąda wysłania przesyłki, system przypisuje drona. Gdy pakiet będzie gotowy do odbioru przez zaplanowanego drona, rozpocznie się proces dostawy. Podczas gdy pakiet jest w transporcie, proces obsługuje dostawę do momentu otrzymania statusu wysłany. Aby uzyskać pełną architekturę referencyjną, zobacz Mikrousługi z Azure Container Apps.
Usługa pobierania odbiera żądania klientów i konwertuje je na komunikaty zawierające szczegóły dotyczące dostawy. Transakcje biznesowe rozpoczynają się po przetworzeniu tych nowych komunikatów przez usługi.
Jedna transakcja biznesowa klienta wymaga trzech odrębnych operacji biznesowych:
Tworzenie lub aktualizowanie pakietu.
Przeznacz drona do dostarczenia przesyłki.
Obsługa dostarczania, w tym sprawdzanie i wysyłanie powiadomienia, gdy pakiet jest dostarczany.
Mikrousługa paczek, harmonogramowanie dronów i mikrousługi dostarczania wykonują procesy biznesowe. Usługi używają komunikatów zamiast centralnego koordynatora do komunikowania się ze sobą. Każda usługa musi z wyprzedzeniem zaimplementować protokół, który koordynuje przepływ pracy biznesowego w sposób zdecentralizowany.
Projektowanie
Usługi przetwarzają transakcje biznesowe w sekwencji za pośrednictwem wielu etapów. Każdy przeskok udostępnia jedną magistralę komunikatów wśród wszystkich usług biznesowych.
Gdy klient wysyła żądanie dostarczenia za pośrednictwem punktu końcowego HTTP, usługa pozyskiwania odbiera je, konwertuje je na komunikat, a następnie publikuje komunikat do udostępnionej magistrali komunikatów. Subskrybowane usługi biznesowe korzystają z nowych komunikatów dodawanych do magistrali. Gdy usługa biznesowa odbierze komunikat, zakończy operację pomyślnie lub żądanie zakończy się niepowodzeniem lub upłynął limit czasu. Jeśli żądanie zakończy się powodzeniem, usługa odpowiada na magistralę z Ok kodem stanu, zgłasza nowy komunikat operacji i wysyła go do magistrali komunikatów. Jeśli żądanie zakończy się niepowodzeniem lub przekroczy limit czasu, usługa przekaże kod przyczyny błędu do magistrali komunikatów i przeniesie wiadomość do kolejki wiadomości niedostarczonych za pośrednictwem Azure Service Bus. Usługa również nieaktywne wiadomości, których nie może odbierać ani przetwarzać w określonym czasie.
Ten projekt używa wielu magistrali komunikatów do przetwarzania całej transakcji biznesowej. Usługi Azure Service Bus i Azure Event Grid udostępniają platformę usługi obsługi komunikatów dla tego projektu. Obciążenie robocze działa w Azure Container Apps. Usługa pozyskiwania działa jako funkcja Azure hostowana w usłudze Container Apps, podczas gdy pakiet, harmonogram dronów i usługi dostarczania działają jako mikrousługi w tym samym środowisku usługi Container Apps. Usługa Container Apps obsługuje przetwarzanie sterowane zdarzeniami , które uruchamia logikę biznesową.
Ten projekt zapewnia również, że choreografia odbywa się w sekwencji. Pojedyncza przestrzeń nazw usługi Service Bus zawiera temat zawierający dwie subskrypcje i kolejkę z obsługą sesji. Usługa pozyskiwania publikuje komunikaty w temacie. Usługa pakietu i usługa harmonogramowania dronów subskrybują tematy i publikują komunikaty, które powiadamiają kolejkę o pomyślnych żądaniach. Dołącz wspólny identyfikator sesji, który kojarzy identyfikator GUID z identyfikatorem dostarczania, aby usługa dostarczania mogła skorelować dwa komunikaty potrzebne dla każdej transakcji. Jedna wiadomość potwierdza, że pakiet jest gotowy, a drugi potwierdza zaplanowanie drona. Bez tej korelacji opartej na sesji usługa dostarczająca nie ma możliwości powiązania związanych ze sobą komunikatów na kolejnych niezależnych etapach przesyłania, ponieważ żaden centralny koordynator nie śledzi stanu transakcji. Usługa dostarczania czeka na dwa powiązane komunikaty dla każdej transakcji. Pierwszy komunikat wskazuje, że przesyłka jest gotowa do wysyłki, a drugi komunikat sygnalizuje, że zaplanowano wysłanie drona.
W tym projekcie usługa Service Bus obsługuje komunikaty o wysokiej wartości, które nie mogą zostać utracone ani zduplikowane podczas całego procesu dostarczania. Po wysłaniu przesyłki, zmiana stanu jest publikowana do usługi Event Grid. Nadawca zdarzeń nie ma oczekiwań co do sposobu obsługi zmiany stanu. Podrzędne usługi organizacji, których ten projekt nie obejmuje, mogą nasłuchiwać tego typu zdarzenia i uruchamiać określoną logikę biznesową, taką jak wysyłanie wiadomości e-mail o stanie zamówienia do użytkownika.
Jeśli wdrażasz ten wzorzec w innej usłudze obliczeniowej, takiej jak AKS, możesz wdrożyć ambassador jako sidecar w tym samym podzie co aplikacja biznesowa. Kolokacja minimalizuje opóźnienie komunikacji, ale serwer proxy dodaje obciążenie przetwarzania i zasobów oraz skaluje je wraz z aplikacją. Użyj tego podejścia, gdy potrzebujesz niezależnych od języka kwestii związanych z łącznością, których platforma nie zapewnia.
Aby uniknąć kaskadowych operacji ponawiania, które mogą prowadzić do wielu prób, usługi biznesowe powinny natychmiast oznaczać niedopuszczalne komunikaty. Wzbogacanie tych komunikatów przy użyciu typowych kodów przyczyn lub zdefiniowanego kodu aplikacji, aby usługi mogły przenieść je do biblioteki DLQ. Rozważ zaimplementowanie wzorca saga w celu zarządzania problemami spójności z usług podrzędnych. Na przykład inna usługa obsługuje wiadomości martwe na potrzeby naprawy tylko przez uruchomienie rekompensaty, ponownych prób lub transakcji przestawnej.
Usługi biznesowe są idempotentne, aby upewnić się, że operacje ponawiania nie tworzą zduplikowanych zasobów. Na przykład usługa pakietowa wykorzystuje operacje upsert do dodawania danych do magazynu danych.
Następny krok
- Zapoznaj się z opcjami asynchronicznych obsługi komunikatów na platformie Azure , aby dowiedzieć się więcej o różnych opcjach infrastruktury dostępnych do implementowania zdecentralizowanego przepływu pracy.
Powiązane zasoby
Weź pod uwagę te wzorce w projekcie choreografii:
Użyj wzorca ambasadora , aby modularyzować komunikację usług biznesowych z magistralą komunikatów.
Zaimplementuj wzorzec równoważenia obciążenia oparty na kolejce, aby obsłużyć skoki obciążenia.
Użyj asynchronicznej rozproszonej obsługi komunikatów za pośrednictwem wzorca Publisher-Subscriber.
Użyj transakcji wyrównywujących , aby cofnąć serię pomyślnych operacji, jeśli co najmniej jedna powiązana operacja zakończy się niepowodzeniem.