Koreografimönster

Koreografimönstret decentraliserar arbetsflödeslogik och distribuerar ansvarsområden till andra komponenter i ett system. I stället för att vara beroende av en central orkestrator, bestämmer tjänsterna när och hur en verksamhetsåtgärd ska bearbetas.

Kontext och problem

Du delar vanligtvis upp ett molnbaserat program i flera små tjänster som fungerar tillsammans för att bearbeta en affärstransaktion från slutpunkt till slutpunkt. En enda åtgärd i en transaktion kan resultera i flera punkt-till-punkt-anrop mellan alla tjänster. Helst är dessa tjänster löst kopplade. Det är svårt att utforma ett distribuerat, effektivt och skalbart arbetsflöde eftersom det omfattar komplex kommunikation mellan tjänster.

Ett vanligt mönster för kommunikation är att använda en centraliserad tjänst eller en orkestrerare. Inkommande begäranden flödar genom orkestratorn när den delegerar åtgärder till respektive tjänster. Varje tjänst slutför sitt ansvar och är inte medveten om det övergripande arbetsflödet.

Ett diagram över ett arbetsflöde som använder en central orkestrerare för att bearbeta begäranden.

Du implementerar vanligtvis orchestrator-mönstret som anpassad programvara som har domänkunskap om ansvaret för tjänsterna i systemet. En fördel med den här metoden är att orkestratorn kan konsolidera statusen för en transaktion baserat på resultatet av enskilda åtgärder som de underordnade tjänsterna utför.

Den här metoden skapar också vissa hinder. Att lägga till eller ta bort tjänster kan bryta befintlig logik eftersom du behöver koppla om delar av kommunikationsvägen. Det här beroendet gör orchestrator-implementeringen komplex och svår att underhålla. Orkestratorn kan påverka arbetsbelastningens tillförlitlighet negativt. Under belastning kan det introducera flaskhalsar för prestanda och vara den enda felpunkten (SPoF). Det kan också orsaka sammanhängande fel i de underordnade tjänsterna.

Lösning

Delegera transaktionshanteringslogik mellan tjänsterna. Låt varje tjänst delta i kommunikationsarbetsflödet för en affärsåtgärd och bestämma när och hur den ska bearbetas.

Koreografimönstret minimerar beroendet av anpassad programvara som centraliserar kommunikationsarbetsflödet. Komponenterna implementerar gemensam logik när de koreografar arbetsflödet sinsemellan utan att kommunicera direkt med varandra.

Ett vanligt sätt att implementera koreografi är att använda en meddelandekö som buffrar begäranden tills underordnade komponenter gör anspråk på och bearbetar dem. Följande bild visar hantering av begäranden via en modell för utgivare och prenumerant.

Ett diagram som visar hur en meddelandekö bearbetar en begäran.

  1. Klienten begär kö som meddelanden i en meddelandeförmedlare.

  2. Tjänsterna eller prenumeranten pollar mäklaren för att avgöra om de kan bearbeta meddelandet utifrån dess implementerade affärslogik. Mäklaren kan också skicka meddelanden till prenumeranter som är intresserade av dem.

  3. Varje prenumererad tjänst utför sin åtgärd enligt vad meddelandet anger och svarar mäklaren med ett meddelande om framgång eller misslyckande.

  4. Om åtgärden lyckas kan tjänsten skicka tillbaka ett meddelande till samma kö eller en annan meddelandekö så att en annan tjänst kan fortsätta arbetsflödet om det behövs. Om åtgärden misslyckas fungerar meddelandekoordinatorn med andra tjänster för att kompensera åtgärden eller hela transaktionen.

Problem och överväganden

Tänk på följande när du bestämmer hur du ska implementera det här mönstret:

När du ska använda det här mönstret

Använd det här mönstret i sådana här scenarier:

  • De underordnade komponenterna hanterar atomiska åtgärder oberoende av varandra. Tänk på det här mönstret som en mekanism för att utlösa och glömma , där en komponent utför en uppgift som inte behöver aktiv hantering. När uppgiften är klar skickar komponenten ett meddelande till de andra komponenterna.

  • Du förväntar dig att ofta uppdatera och ersätta komponenterna. Med det här mönstret kan du ändra programmet med mindre ansträngning och minimala avbrott i befintliga tjänster.

  • Du använder serverlösa arkitekturer för enkla arbetsflöden. Komponenterna kan vara kortvariga och händelsedrivna. När en händelse inträffar skapar tjänsten komponenter som utför en uppgift och tjänsten tar bort komponenter när de har slutfört den uppgiften.

  • Kommunikation mellan avgränsade kontexter kräver lös koppling över domängränser. För kommunikation i en enda begränsad kontext använder du ett orchestrator-mönster i stället.

  • Den centrala orkestratorn introducerar en flaskhals i prestandan.

Det här mönstret kanske inte är lämpligt när:

  • Programmet är komplext och kräver en central komponent för att hantera delad logik för att hålla nedströmskomponenterna lätta.

  • Punkt-till-punkt-kommunikation mellan komponenterna är oundviklig.

  • Du måste använda affärslogik för att konsolidera alla åtgärder som underordnade komponenter hanterar.

Design av arbetsbelastning

Utvärdera hur du använder koreografimönstret i en arbetsbelastnings design för att hantera de mål och principer som beskrivs i Grundpelarna i Azure Well-Architected Framework. Följande tabell innehåller vägledning om hur det här mönstret stöder målen för varje pelare.

Grundpelare Så här stöder det här mönstret pelarmål
Operational Excellence hjälper till att leverera arbetsbelastningskvalitet genom standardiserade processer och teamsammanhållning. De distribuerade komponenterna i det här mönstret är autonoma och utformade för att vara utbytbara, så du kan ändra arbetsbelastningen med mindre övergripande ändringar i systemet.

- OE:04 Verktyg och processer
Prestandaeffektivitet hjälper din arbetsbelastning effektivt uppfylla kraven genom optimering av skalning, data och kod. Det här mönstret erbjuder ett alternativ när prestandaflaskhalsar uppstår i en centraliserad orkestreringstoppologi.

- PE:02 Kapacitetsplanering
- PE:05 Skalning och partitionering

Om detta mönster inför kompromisser inom en pelare bör du överväga dem mot målen för de andra pelarna.

Exempel

Det här exemplet visar koreografimönstret genom att skapa en händelsedriven, molnbaserad arbetsbelastning som kör funktioner tillsammans med mikrotjänster. När en klient begär att skicka ett paket tilldelar arbetsbelastningen en drönare. När paketet är klart för upphämtning av den schemalagda drönaren startar leveransprocessen. Medan paketet är under transport hanterar arbetsflödet leveransen tills det tar emot den skickade statusen.

Diagram över en händelsedriven, molnbaserad exempelarbetsbelastning som implementerar koreografimönstret.

Inmatningstjänsten tar emot klientbegäranden och konverterar dem till meddelanden som innehåller leveransinformation. Affärstransaktioner startar efter att tjänsterna har förbrukat de nya meddelandena.

En enskild klientaffärstransaktion kräver tre distinkta affärsåtgärder:

  • Skapa eller uppdatera ett paket.

  • Tilldela en drönare för att leverera paketet.

  • Hantera leveransen, inklusive att kontrollera och skicka ett meddelande när paketet levereras.

Paket-, drone scheduler- och leveransmikrotjänster utför affärsbearbetningen. Tjänsterna använder meddelanden i stället för en central orkestrerare för att kommunicera med varandra. Varje tjänst måste implementera ett protokoll i förväg som samordnar affärsarbetsflödet på ett decentraliserat sätt.

Design

Tjänster bearbetar affärstransaktioner i en sekvens genom flera hopp. Varje hopp delar en enda meddelandebuss mellan alla affärstjänster.

När en klient skickar en leveransbegäran via en HTTP-slutpunkt tar inmatningstjänsten emot den, konverterar den till ett meddelande och publicerar sedan meddelandet till den delade meddelandebussen. De prenumerationsbaserade affärstjänsterna använder nya meddelanden som lagts till i bussen. När en företagstjänst tar emot meddelandet slutförs åtgärden eller begäran misslyckas eller överskrider tidsgränsen. Om begäran lyckas svarar tjänsten på bussen med Ok statuskoden, genererar ett nytt åtgärdsmeddelande och skickar det till meddelandebussen. Om begäran misslyckas eller överskrider tidsgränsen rapporterar tjänsten fel genom att skicka orsakskoden till meddelandebussen och lägger sedan till meddelandet i en kö med obeställbara meddelanden (DLQ). Tjänsten flyttar också meddelanden som den inte kan ta emot eller bearbeta inom en viss tid till DLQ.

Den här designen använder flera meddelandebussar för att bearbeta hela affärstransaktionen. Azure Service Bus och Azure Event Grid tillhandahåller meddelandetjänstplattformen för den här designen. Arbetsbelastningen körs på Azure Container Apps, som är värd för Azure Functions för inmatning. Container Apps hanterar händelsedriven bearbetning som kör affärslogik.

Den här designen säkerställer också att koreografin förekommer i en sekvens. Ett enda Service Bus-namnområde innehåller ett ämne som har två prenumerationer och en sessionsmedveten kö. Inmatningstjänsten publicerar meddelanden på ämnesområdet. Pakettjänsten och drönarschemaläggningstjänsten prenumererar på ett ämne och publicerar meddelanden som informerar kön om lyckade begäranden. Inkludera en vanlig sessionsidentifierare som associerar ett GUID med leveransidentifieraren så att tjänsterna kan hantera obundna sekvenser av relaterade meddelanden i ordning. Leveranstjänsten väntar på två relaterade meddelanden för varje transaktion. Det första meddelandet anger att paketet är redo att levereras och det andra meddelandet signalerar att en drönare är schemalagd.

I den här designen hanterar Service Bus värdefulla meddelanden som inte får gå förlorade eller dupliceras under hela leveransprocessen. När paketet levereras publiceras en tillståndsändring till Event Grid. Händelsesändaren har inga förväntningar på hur tillståndsändringen ska hanteras. Underordnade organisationstjänster som den här designen inte innehåller kan lyssna efter den här händelsetypen och köra specifik affärslogik, till exempel att skicka ett e-postmeddelande med orderstatus till användaren.

Om du distribuerar det här mönstret i en annan beräkningstjänst, till exempel AKS, kan du implementera Publisher-Subscriber-mönsterprogrammets pannplåt med två containrar i samma podd. En container kör ambassador som interagerar med den meddelandebuss du väljer medan den andra containern kör affärslogik. Den här metoden förbättrar prestanda och skalbarhet. Ambassadören och företagstjänsten delar samma nätverk, vilket minskar svarstiden och ökar dataflödet.

För att undvika sammanhängande återförsöksåtgärder som kan leda till flera försök bör företagstjänster omedelbart flagga oacceptabla meddelanden. Utöka dessa meddelanden med hjälp av vanliga orsakskoder eller en definierad programkod så att tjänsterna kan flytta dem till en DLQ. Överväg att implementera Saga-mönstret för att hantera konsekvensproblem från underordnade tjänster. En annan tjänst hanterar till exempel meddelanden med dead-letter endast i reparationssyfte genom att köra en kompensation, ett nytt försök eller en pivottransaktion.

Affärstjänsterna är idempotenta för att säkerställa att återförsök inte skapar dubbletter av resurser. Pakettjänsten använder till exempel upsert-åtgärder för att lägga till data i datalagret.

Nästa steg

Tänk på dessa mönster i din design för koreografi: