Werkstroomlogica decentraliseren en de verantwoordelijkheden distribueren naar andere onderdelen binnen een systeem.
Context en probleem
Een cloudtoepassing is vaak onderverdeeld in verschillende kleine services die samenwerken om een zakelijke transactie end-to-end te verwerken. Zelfs één bewerking (binnen een transactie) kan leiden tot meerdere punt-naar-punt-aanroepen tussen alle services. In het ideale geval moeten deze services losjes worden gekoppeld. Het is lastig om een werkstroom te ontwerpen die gedistribueerd, efficiënt en schaalbaar is, omdat het vaak complexe communicatie tussen services omvat.
Een algemeen patroon voor communicatie is het gebruik van een gecentraliseerde service of een orchestrator. Binnenkomende aanvragen stromen via de orchestrator terwijl deze bewerkingen delegeert aan de respectieve services. Elke service voltooit alleen de verantwoordelijkheid en is niet op de hoogte van de algehele werkstroom.
Het orchestratorpatroon wordt doorgaans geïmplementeerd als aangepaste software en heeft domeinkennis over de verantwoordelijkheden van deze services. Een voordeel is dat de orchestrator de status van een transactie kan consolideren op basis van de resultaten van afzonderlijke bewerkingen die worden uitgevoerd door de downstreamservices.
Er zijn echter enkele nadelen. Het toevoegen of verwijderen van services kan bestaande logica verbreken omdat u delen van het communicatiepad opnieuw moet instellen. Deze afhankelijkheid maakt orchestrator-implementatie complex en moeilijk te onderhouden. De orchestrator kan een negatieve invloed hebben op de betrouwbaarheid van de workload. Onder belasting kan het prestatieknelpunt veroorzaken en het single point of failure zijn. Het kan ook trapsgewijze fouten veroorzaken in de downstreamservices.
Oplossing
De transactieafhandelingslogica delegeren tussen de services. Laat elke service beslissen en deelnemen aan de communicatiewerkstroom voor een bedrijfsbewerking.
Het patroon is een manier om de afhankelijkheid van aangepaste software te minimaliseren die de communicatiewerkstroom centraliseert. De onderdelen implementeren algemene logica terwijl ze de werkstroom onder elkaar choreograferen zonder directe communicatie met elkaar te hebben.
Een veelgebruikte manier om choreografie te implementeren, is door een berichtenbroker te gebruiken die aanvragen buffert totdat downstreamonderdelen deze claimen en verwerken. In de afbeelding ziet u de verwerking van aanvragen via een model voor uitgeversabonnee.
Een clientaanvragen worden in de wachtrij geplaatst als berichten in een berichtenbroker.
De services of de abonnee peilen de broker om te bepalen of ze dat bericht kunnen verwerken op basis van hun geïmplementeerde bedrijfslogica. De broker kan ook berichten pushen naar abonnees die geïnteresseerd zijn in dat bericht.
Elke geabonneerde service voert de bewerking uit zoals aangegeven door het bericht en reageert op de broker met succes of mislukking van de bewerking.
Als dit lukt, kan de service een bericht terugsturen naar dezelfde wachtrij of een andere berichtenwachtrij, zodat een andere service de werkstroom indien nodig kan voortzetten. Als de bewerking mislukt, werkt de berichtenbroker met andere services om die bewerking of de hele transactie te compenseren.
Problemen en overwegingen
Het decentraliseren van de orchestrator kan problemen veroorzaken tijdens het beheren van de werkstroom.
Het kan lastig zijn om fouten te overhandigen. Onderdelen in een toepassing kunnen atomische taken uitvoeren, maar ze hebben mogelijk nog steeds een afhankelijkheidsniveau. Fout in het ene onderdeel kan van invloed zijn op andere onderdelen, wat kan leiden tot vertragingen bij het voltooien van de algehele aanvraag.
Als u fouten probleemloos wilt afhandelen, kan het implementeren van compenserende transacties complexiteit veroorzaken. Foutafhandelingslogica, zoals compenserende transacties, is ook gevoelig voor fouten.
Het patroon is geschikt voor een werkstroom waarbij onafhankelijke bedrijfsactiviteiten parallel worden verwerkt. De werkstroom kan ingewikkeld worden wanneer choreograaf in een reeks moet plaatsvinden. Service D kan de bewerking bijvoorbeeld pas starten nadat Service B en Service C hun bewerkingen met succes hebben voltooid.
Het patroon wordt een uitdaging als het aantal services snel groeit. Gezien het grote aantal onafhankelijke bewegende onderdelen, wordt de werkstroom tussen services meestal complex. Gedistribueerde tracering wordt ook moeilijk, hoewel hulpprogramma's zoals ServiceInsight samen met NServiceBus deze uitdagingen kunnen verminderen.
In een orchestrator-geleid ontwerp kan het centrale onderdeel gedeeltelijk deelnemen aan en tolerantielogica delegeren aan een ander onderdeel dat tijdelijke, niet-tijdelijke en time-outfouten consistent opnieuw probeert uit te proberen. Met de ontbinding van de orchestrator in het choreografiepatroon moeten de downstreamonderdelen deze tolerantietaken niet ophalen. Deze moeten nog steeds worden verwerkt door de tolerantiehandler. Maar nu moeten de downstreamonderdelen rechtstreeks communiceren met de tolerantiehandler, waardoor de point-to-point-communicatie toeneemt.
Wanneer dit patroon gebruiken
Gebruik dit patroon wanneer:
De downstreamonderdelen verwerken atomische bewerkingen onafhankelijk. Beschouw het als een 'brand en vergeet'-mechanisme. Een onderdeel is verantwoordelijk voor een taak die niet actief hoeft te worden beheerd. Wanneer de taak is voltooid, wordt er een melding naar de andere onderdelen verzonden.
De onderdelen worden naar verwachting regelmatig bijgewerkt en vervangen. Met het patroon kan de toepassing met minder inspanning en minimale onderbreking van bestaande services worden gewijzigd.
Het patroon is natuurlijk geschikt voor serverloze architecturen die geschikt zijn voor eenvoudige werkstromen. De onderdelen kunnen kortlevend en gebeurtenisgestuurd zijn. Wanneer er een gebeurtenis optreedt, worden onderdelen uitgesponnen, hun taken uitgevoerd en verwijderd zodra de taak is voltooid.
Dit patroon kan een goede keuze zijn voor communicatie tussen contextgrenzen. Voor communicatie binnen een individuele gebonden context kan een orchestratorpatroon worden overwogen.
Er is prestatieknelpunten geïntroduceerd door de centrale orchestrator.
In de volgende gevallen is dit patroon mogelijk niet geschikt:
De toepassing is complex en vereist een centraal onderdeel voor het verwerken van gedeelde logica om de downstreamonderdelen lichtgewicht te houden.
Er zijn situaties waarin punt-naar-punt-communicatie tussen de onderdelen onvermijdelijk is.
U moet alle bewerkingen die worden verwerkt door downstreamonderdelen samenvoegen met behulp van bedrijfslogica.
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.
De opnameservice verwerkt clientaanvragen en converteert deze naar berichten, inclusief de bezorgingsdetails. Zakelijke transacties worden gestart nadat deze nieuwe berichten zijn gebruikt.
Voor één clientbedrijfstransactie zijn drie afzonderlijke bedrijfsactiviteiten vereist:
- Een pakket maken of bijwerken
- Een drone toewijzen om het pakket te leveren
- De levering afhandelen die bestaat uit het controleren en uiteindelijk vergroten van het bewustzijn wanneer ze worden verzonden.
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 toegevoegd aan een wachtrij met onbestelbare berichten. 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 boilerplate, 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 dode brieven verwerken voor hersteldoeleinden door een compensatie uit te voeren, opnieuw te proberen of een 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.
Verwante resources
Houd rekening met deze patronen in uw ontwerp voor choreografie.
Modulariseer de zakelijke service met behulp van het ontwerppatroon ambassadeur.
Implementeer een load leveling-patroon op basis van wachtrijen om pieken van de werkbelasting te verwerken.
Gebruik asynchrone gedistribueerde berichten via het patroon uitgeversabonnee.
Gebruik compenserende transacties om een reeks geslaagde bewerkingen ongedaan te maken voor het geval een of meer gerelateerde bewerkingen mislukken.
Zie Asynchrone berichtopties in Azure voor informatie over het gebruik van een berichtenbroker in een berichteninfrastructuur.