Choreograafpatroon

Azure Event Grid
Azure Service Bus

Zorg ervoor dat elk onderdeel van het systeem deelneemt aan het besluitvormingsproces over de werkstroom van een zakelijke transactie, in plaats van te vertrouwen op een centraal controlepunt.

Context en probleem

In de microservicesarchitectuur is het vaak zo dat een cloudtoepassing is onderverdeeld in verschillende kleine services die samenwerken om een zakelijke transactie end-to-end te verwerken. Als u de koppeling tussen services wilt verlagen, is elke service verantwoordelijk voor één bedrijfsbewerking. Enkele voordelen zijn snellere ontwikkeling, kleinere codebasis en schaalbaarheid. Het ontwerpen van een efficiënte en schaalbare werkstroom is echter een uitdaging en vereist vaak complexe communicatie tussen services.

De services communiceren met elkaar met behulp van goed gedefinieerde API's. Zelfs één bedrijfsbewerking kan leiden tot meerdere punt-naar-punt-aanroepen tussen alle services. Een algemeen patroon voor communicatie is het gebruik van een gecentraliseerde service die fungeert als orchestrator. Het erkent alle binnenkomende aanvragen en delegeert bewerkingen voor de respectieve services. Hierbij wordt ook de werkstroom van de hele zakelijke transactie beheerd. Elke service voltooit een bewerking en is niet op de hoogte van de algehele werkstroom.

Het orchestratorpatroon vermindert punt-naar-punt-communicatie tussen services, maar heeft enkele nadelen vanwege de nauwe koppeling tussen de orchestrator en andere services die deelnemen aan de verwerking van de zakelijke transactie. Als u taken in een reeks wilt uitvoeren, moet de orchestrator enige domeinkennis hebben over de verantwoordelijkheden van deze services. Als u services wilt toevoegen of verwijderen, wordt de bestaande logica verbroken en moet u delen van het communicatiepad opnieuw instellen. Hoewel u de werkstroom kunt configureren, kunt u eenvoudig services toevoegen of verwijderen met een goed ontworpen orchestrator, is een dergelijke implementatie complex en moeilijk te onderhouden.

Een aanvraag verwerken met behulp van een centrale orchestrator

Oplossing

Laat elke service bepalen wanneer en hoe een bedrijfsbewerking wordt verwerkt, in plaats van afhankelijk te zijn van een centrale orchestrator.

Een manier om choreografie te implementeren, is door het asynchrone berichtenpatroon te gebruiken om de bedrijfsactiviteiten te coördineren.

Een aanvraag verwerken met een choreograaf

Een clientaanvraag publiceert berichten naar een berichtenwachtrij. Wanneer berichten binnenkomen, worden ze gepusht naar abonnees of services die geïnteresseerd zijn in dat bericht. Elke geabonneerde service voert de bewerking uit zoals aangegeven door het bericht en reageert op de berichtenwachtrij met succes of mislukking van de bewerking. In het geval van succes kan de service een bericht terugsturen naar dezelfde wachtrij of een andere berichtenwachtrij, zodat een andere service de werkstroom indien nodig kan voortzetten. Als een bewerking mislukt, kan de berichtenbus die bewerking opnieuw proberen.

Op deze manier choreograferen de diensten de werkstroom onder elkaar zonder dat ze afhankelijk zijn van een orchestrator of directe communicatie tussen hen hebben.

Omdat er geen punt-naar-punt-communicatie is, helpt dit patroon de koppeling tussen services te verminderen. Het kan ook het prestatieknelpunt verwijderen dat wordt veroorzaakt door de orchestrator wanneer deze te maken heeft met alle transacties.

Wanneer dit patroon gebruiken

Gebruik het choreografiepatroon als u verwacht dat u services regelmatig bijwerkt of vervangt en bepaalde services uiteindelijk toevoegt of verwijdert. De hele app kan met minder inspanning en minimale onderbreking van bestaande services worden gewijzigd.

Houd rekening met dit patroon als u prestatieknelpunten ondervindt in de centrale orchestrator.

Dit patroon is een natuurlijk model voor de serverloze architectuur, waarbij alle services kort kunnen leven of gebeurtenisgestuurd kunnen zijn. Services kunnen worden uitgevoerd vanwege een gebeurtenis, hun taak uitvoeren en worden verwijderd wanneer de taak is voltooid.

Problemen en overwegingen

Het decentraliseren van de orchestrator kan problemen veroorzaken tijdens het beheren van de werkstroom.

Als een service een bedrijfsbewerking niet kan voltooien, kan het lastig zijn om deze fout te herstellen. Een manier is om de service te laten wijzen op een fout door een gebeurtenis te starten. Een andere service abonneert zich op deze mislukte gebeurtenissen, neemt noodzakelijke acties, zoals het toepassen van compenserende transacties om geslaagde bewerkingen in een aanvraag ongedaan te maken. De mislukte service kan ook een gebeurtenis voor de fout niet activeren. In dat geval kunt u overwegen een mechanisme voor opnieuw proberen en of time-out gebruiken om die bewerking te herkennen als een fout. Zie de sectie Voorbeeld voor een voorbeeld.

Het is eenvoudig om een werkstroom te implementeren wanneer u onafhankelijke bedrijfsactiviteiten parallel wilt verwerken. U kunt één berichtenbus gebruiken. De werkstroom kan echter ingewikkeld worden wanneer choreograaf in een reeks moet plaatsvinden. Service C kan de bewerking bijvoorbeeld pas starten nadat Service A en Service B hun bewerkingen met succes hebben voltooid. Een benadering is om meerdere berichtenbussen of wachtrijen te hebben die berichten in de vereiste volgorde ontvangen. Zie de sectie Voorbeeld voor meer informatie.

Het choreografiepatroon wordt een uitdaging als het aantal diensten snel groeit. Gezien het grote aantal onafhankelijke bewegende onderdelen, wordt de werkstroom tussen services meestal complex. Gedistribueerde tracering wordt ook moeilijk.

De orchestrator beheert de tolerantie van de werkstroom centraal en kan een single point of failure worden. Aan de andere kant, voor choreografie, wordt de rol verdeeld over alle diensten en tolerantie wordt minder robuust.

Elke service is niet alleen verantwoordelijk voor de tolerantie van de bewerking, maar ook voor de werkstroom. Deze verantwoordelijkheid kan lastig zijn voor de service en moeilijk te implementeren. Elke service moet tijdelijke, niet-tijdelijke en time-outfouten opnieuw proberen, zodat de aanvraag, indien nodig, correct wordt beëindigd. Bovendien moet de service ijverig zijn over het communiceren van het succes of falen van de bewerking, zodat andere services dienovereenkomstig kunnen handelen.

Workloadontwerp

Een architect moet evalueren hoe het choreograafpatroon kan worden gebruikt in het ontwerp van hun workload om de doelstellingen en principes te verhelpen die worden behandeld in de pijlers van het Azure Well-Architected Framework. Voorbeeld:

Pijler Hoe dit patroon ondersteuning biedt voor pijlerdoelen
Operational Excellence helpt bij het leveren van workloadkwaliteit via gestandaardiseerde processen en teamcohesie. Omdat de gedistribueerde onderdelen in dit patroon autonoom zijn en zijn ontworpen om te worden vervangen, kunt u de werkbelasting wijzigen door minder algemene wijzigingen in het systeem.

- OE:04 Hulpprogramma's en processen
Prestatie-efficiëntie helpt uw workload efficiënt te voldoen aan de vereisten door optimalisaties in schalen, gegevens, code. Dit patroon biedt een alternatief wanneer prestatieknelpunten optreden in een gecentraliseerde indelingstopologie.

- PE:02 Capaciteitsplanning
- PE:05 Schalen en partitioneren

Net als bij elke ontwerpbeslissing moet u rekening houden met eventuele compromissen ten opzichte van de doelstellingen van de andere pijlers die met dit patroon kunnen worden geïntroduceerd.

Opmerking

In dit voorbeeld ziet u het choreografiepatroon door een gebeurtenisgestuurde, cloudeigen workload met functies samen met microservices te maken. Wanneer een client een pakket aanvraagt om te worden verzonden, wijst de workload een drone toe. Zodra het pakket klaar is om te worden opgehaald door de geplande drone, wordt het leveringsproces gestart. Tijdens de overdracht verwerkt de workload de levering totdat deze de verzonden status krijgt.

Dit voorbeeld is een herstructurering van de Drone Delivery-implementatie die het Orchestrator-patroon vervangt door het choreograafpatroon.

Diagram van een gebeurtenisgestuurde cloudeigen voorbeeldworkload voor het implementeren van een choreografiepatroon

De opnameservice verwerkt de clientaanvragen en converteert deze naar berichten, inclusief de bezorgingsgegevens. Zakelijke transacties worden gestart nadat deze nieuwe berichten zijn gebruikt.

Eén zakelijke transactie van één klant vereist drie afzonderlijke bedrijfsactiviteiten: het maken of bijwerken van een pakket, het toewijzen van een drone voor het leveren van het pakket en de juiste verwerking van de levering die bestaat uit het controleren en uiteindelijk vergroten van de bekendheid bij verzending. Drie microservices voeren de bedrijfsprocessen uit: Pakket-, Drone Scheduler- en Leveringsservices. In plaats van een centrale orchestrator gebruiken de services berichten om onderling te communiceren. Elke service zou verantwoordelijk zijn voor het implementeren van een protocol vooraf dat coördineert op een gedecentraliseerd manier waarop de bedrijfswerkstroom.

Ontwerpen

De zakelijke transactie wordt in een reeks verwerkt via meerdere hops. Elke hop deelt één berichtenbus tussen alle zakelijke services.

Wanneer een client een bezorgingsaanvraag verzendt via een HTTP-eindpunt, ontvangt de opnameservice deze, converteert deze aanvraag naar een bericht en publiceert het bericht vervolgens naar de gedeelde berichtenbus. De geabonneerde zakelijke services gebruiken nieuwe berichten die aan de bus zijn toegevoegd. Bij het ontvangen van het bericht kunnen de zakelijke services de bewerking voltooien met succes, mislukt of kan er een time-out optreden voor de aanvraag. Als dit lukt, reageren de services op de bus met de statuscode OK, wordt een nieuw bewerkingsbericht verzonden en verzonden naar de berichtenbus. Als er een fout of time-out optreedt, meldt de service een fout door de redencode naar de berichtenbus te verzenden. Daarnaast wordt het bericht dood geschreven voor latere verwerking. Berichten die niet binnen een redelijke en geschikte tijd kunnen worden ontvangen of verwerkt, worden ook verplaatst naar de DLQ.

Het ontwerp maakt gebruik van meerdere berichtenbussen om de hele zakelijke transactie te verwerken. Microsoft Azure Service Bus en Microsoft Azure Event Grid zijn samengesteld om het berichtenserviceplatform voor dit ontwerp te bieden. De workload wordt geïmplementeerd in Azure Container Apps die als host fungeert voor Azure Functions voor opname en apps die gebeurtenisgestuurde verwerking verwerken die de bedrijfslogica uitvoert.

Het ontwerp zorgt ervoor dat de choreografie in een reeks plaatsvindt. Eén Azure Service Bus-naamruimte bevat een onderwerp met twee abonnementen en een sessiebewuste wachtrij. De opnameservice publiceert berichten naar het onderwerp. De Pakketservice en Drone Scheduler-service abonneren zich op het onderwerp en publiceren berichten die het succes met de wachtrij communiceren. Als u een algemene sessie-id opgeeft die een GUID aan de leverings-id is gekoppeld, kunt u de geordende verwerking van niet-gebonden reeksen gerelateerde berichten mogelijk maken. De bezorgingsservice wacht op twee gerelateerde berichten per transactie. Het eerste bericht geeft aan dat het pakket gereed is om te worden verzonden en de tweede signalen dat een drone is gepland.

Dit ontwerp maakt gebruik van Azure Service Bus om hoogwaardige berichten af te handelen die niet verloren kunnen gaan of worden gedupliceerd tijdens het hele bezorgingsproces. Wanneer het pakket wordt verzonden, wordt er ook een wijziging van de status gepubliceerd naar Azure Event Grid. In dit ontwerp heeft de afzender van de gebeurtenis geen verwachting over hoe de statuswijziging wordt verwerkt. Downstream-organisatieservices die niet zijn opgenomen als onderdeel van dit ontwerp, kunnen luisteren naar dit gebeurtenistype en reageren op het uitvoeren van specifieke bedrijfsdoellogica (dat wil gezegd, e-mail de verzonden orderstatus naar de gebruiker).

Als u van plan bent om dit te implementeren in een andere rekenservice, zoals AKS pub-sub pattern application boilplate, kan worden geïmplementeerd met twee containers in dezelfde pod. De ene container voert de ambassadeur uit die communiceert met uw berichtenbus van voorkeur terwijl de andere de bedrijfslogica uitvoert. De aanpak met twee containers in dezelfde pod verbetert de prestaties en schaalbaarheid. De ambassadeur en de bedrijfsservice delen hetzelfde netwerk, waardoor lage latentie en hoge doorvoer mogelijk zijn.

Om trapsgewijze bewerkingen voor opnieuw proberen te voorkomen die tot meerdere inspanningen kunnen leiden, moeten zakelijke services onmiddellijk onaanvaardbare berichten markeren. Het is mogelijk om dergelijke berichten te verrijken met behulp van bekende redencodes of een gedefinieerde toepassingscode, zodat deze kan worden verplaatst naar een wachtrij met dode letters (DLQ). Overweeg consistentieproblemen te beheren bij het implementeren van Saga vanuit downstreamservices. Een andere service kan bijvoorbeeld alleen berichten met onbeletterde berichten verwerken voor hersteldoeleinden door een compensatie, rety- of draaitransactie uit te voeren.

De zakelijke services zijn idempotent om ervoor te zorgen dat bewerkingen voor opnieuw proberen niet resulteren in dubbele resources. De Package-service maakt bijvoorbeeld gebruik van upsert-bewerkingen om gegevens toe te voegen aan het gegevensarchief.

Houd rekening met deze patronen in uw ontwerp voor choreografie.