Dela via


Händelsedriven arkitekturstil

En händelsedriven arkitektur består av händelseproducenter som genererar en ström av händelser, händelsekonsumenter som lyssnar efter dessa händelser och händelsekanaler (som ofta implementeras som händelsekoordinatorer eller inmatningstjänster) som överför händelser från producenter till konsumenter.

Architecture

Diagram som visar ett händelsedrivet arkitekturformat.

Händelser levereras nästan i realtid, så att konsumenterna kan svara omedelbart på händelser när de inträffar. Producenterna frikopplas från konsumenterna, vilket innebär att en producent inte vet vilka konsumenter som lyssnar. Konsumenterna är också frikopplade från varandra, och varje konsument ser alla händelser.

Den här processen skiljer sig från ett mönster för konkurrerande konsumenter. I mönstret Konkurrerande konsumenter hämtar konsumenter meddelanden från en kö. Varje meddelande bearbetas bara en gång, förutsatt att det inte finns några fel. I vissa system, till exempel Azure IoT, måste händelser matas in på höga volymer.

En händelsedriven arkitektur kan använda en publiceringsprenumereringsmodell eller en händelseströmsmodell.

  • Publicera-prenumerera: Infrastrukturen för publiceringsprenumerationer spårar prenumerationer. När en händelse publiceras skickar den händelsen till varje prenumerant. När händelsen har levererats kan den inte spelas upp igen och nya prenumeranter ser inte händelsen. Vi rekommenderar att du använder Azure Event Grid för publiceringsprenumereringsscenarier.

  • Händelseströmning: Händelser skrivs till en logg. Händelser är strikt ordnade inom en partition och är varaktiga. Klienter prenumererar inte på strömmen. I stället kan en klient läsa från vilken del av strömmen som helst. Klienten ansvarar för att avancera sin position i dataströmmen, vilket innebär att en klient kan ansluta när som helst och kan spela upp händelser igen. Azure Event Hubs är utformat för händelseströmning med högt dataflöde.

På konsumentsidan finns det några vanliga varianter:

  • Enkel händelsebearbetning: En händelse utlöser omedelbart en åtgärd i konsumenten. Du kan till exempel använda Azure Functions med en Event Grid-utlösare eller Azure Service Bus-utlösare så att koden körs när ett meddelande publiceras.

  • Grundläggande händelsekorrelation: En konsument bearbetar några diskreta affärshändelser, korrelerar dem med en identifierare och bevarar information från tidigare händelser som ska användas när den bearbetar senare händelser. Bibliotek som NServiceBus och MassTransit stöder det här mönstret.

  • Komplex händelsebearbetning: En konsument använder en teknik som Azure Stream Analytics för att analysera en serie händelser och identifiera mönster i händelsedata. Du kan till exempel aggregera avläsningar från en inbäddad enhet under en tidsperiod och generera ett meddelande om glidande medelvärde överskrider ett visst tröskelvärde.

  • Bearbetning av händelseström: Använd en dataströmningsplattform, till exempel Azure IoT Hub, Event Hubs eller Event Hubs för Apache Kafka, som en pipeline för att mata in händelser och mata in dem för att strömma processorer. Dataströmprocessorerna fungerar för att bearbeta eller transformera strömmen. Det kan finnas flera dataströmprocessorer för olika undersystem i programmet. Den här metoden passar bra för IoT-arbetsbelastningar.

Källan till händelserna kan vara extern för systemet, till exempel fysiska enheter i en IoT-lösning. I så fall måste systemet kunna mata in data på den volym och det dataflöde som datakällan kräver.

Det finns två huvudsakliga metoder för att strukturera händelsenyttolaster. När du har kontroll över dina händelsekonsumenter kan du bestämma nyttolaststrukturen för varje konsument. Med den här strategin kan du blanda metoder efter behov i en enda arbetsbelastning.

  • Inkludera alla obligatoriska attribut i nyttolasten: Använd den här metoden när du vill att konsumenterna ska ha all tillgänglig information utan att behöva fråga en extern datakälla. Det kan dock leda till datakonsekvensproblem på grund av flera postsystem, särskilt efter uppdateringar. Avtalshantering och versionshantering kan också bli komplexa.

  • Inkludera endast nycklar i nyttolasten: I den här metoden hämtar konsumenterna de attribut som behövs, till exempel en primärnyckel, för att oberoende hämta återstående data från en datakälla. Den här metoden ger bättre datakonsekvens eftersom den har ett enda postsystem. Den kan dock prestera sämre än den första metoden eftersom konsumenterna ofta måste fråga datakällan. Du har färre problem med koppling, bandbredd, kontraktshantering eller versionshantering eftersom mindre händelser och enklare kontrakt minskar komplexiteten.

I föregående diagram visas varje typ av konsument som en enda ruta. För att undvika att konsumenten blir en enskild felpunkt i systemet är det vanligt att ha flera instanser av en konsument. Flera instanser kan också krävas för att hantera volymen och frekvensen för händelser. En enskild konsument kan bearbeta händelser i flera trådar. Den här konfigurationen kan skapa utmaningar om händelser måste bearbetas i ordning eller kräver exakt en gång semantik. Mer information finns i Minimera samordning.

Det finns två primära topologier i många händelsedrivna arkitekturer:

  • Topologi för asynkron meddelandekö: Komponenter sänder händelser till hela systemet. Andra komponenter agerar antingen på händelsen eller ignorerar händelsen. Den här topologin är användbar när händelsebearbetningsflödet är relativt enkelt. Det finns ingen central samordning eller orkestrering, så den här topologin kan vara dynamisk.

    Den här topologin är mycket frikopplad, vilket ger skalbarhet, svarstider och feltolerans för komponenter. Ingen komponent äger eller känner till tillståndet för en affärstransaktion med flera steg och åtgärder vidtas asynkront. Därför är distribuerade transaktioner riskfyllda eftersom det inte finns någon inbyggd mekanism för att starta om eller spela upp dem igen. Du måste noga överväga strategier för felhantering och manuella åtgärder eftersom den här topologin kan vara en källa till datainkonsekvens.

  • Topologi för medlare: Den här topologin åtgärdar några av bristerna i koordinatortopologin. Det finns en händelsemedlare som hanterar och styr händelseflödet. Händelsemedlaren underhåller tillståndet och hanterar funktioner för felhantering och omstart. Till skillnad från koordinatortopologin sänder komponenterna i medlartopologin förekomster som kommandon och endast till avsedda kanaler. Dessa kanaler är ofta meddelandeköer. Konsumenterna förväntas bearbeta dessa kommandon.

    Den här topologin ger mer kontroll, bättre distribuerad felhantering och potentiellt bättre datakonsekvens. Den här topologin medför dock ökad koppling mellan komponenter, och händelsemedlaren kan bli en flaskhals eller ett tillförlitlighetsproblem.

När du ska använda den här arkitekturen

Du bör använda den här arkitekturen när följande villkor är uppfyllda:

  • Flera undersystem måste bearbeta samma händelser.

  • Realtidsbearbetning med minsta tidsfördröjning krävs.

  • Komplex händelsebearbetning, till exempel mönstermatchning eller aggregering över tidsfönster, krävs.

  • Hög volym och hög datahastighet krävs, till exempel med IoT.

  • Du måste frikoppla producenter och konsumenter för oberoende skalbarhets- och tillförlitlighetsmål.

Fördelar

Den här arkitekturen ger följande fördelar:

  • Producenter och konsumenter är frikopplade.
  • Det finns inga punkt-till-punkt-integreringar. Det är enkelt att lägga till nya konsumenter i systemet.
  • Konsumenter kan svara på händelser omedelbart när de inträffar.
  • Den är mycket skalbar, elastisk och distribuerad.
  • Undersystem har oberoende vyer av händelseströmmen.

Utmaningar

  • Garanterad leverans

    I vissa system, särskilt i IoT-scenarier, är det viktigt att garantera att händelser levereras.

  • Bearbeta händelser i ordning eller bara en gång

    För återhämtning och skalbarhet körs varje konsumenttyp vanligtvis i flera instanser. Den här processen kan skapa en utmaning om händelserna måste bearbetas i ordning inom en konsumenttyp eller om idempotent meddelandebearbetningslogik inte implementeras.

  • Meddelandesamordning mellan tjänster

    Affärsprocesser har ofta flera tjänster som publicerar och prenumererar på meddelanden för att uppnå ett konsekvent resultat för en hel arbetsbelastning. Du kan använda arbetsflödesmönster som koreografi och Saga Orchestration för att hantera meddelandeflöden på ett tillförlitligt sätt mellan olika tjänster.

  • Felhantering

    Händelsedriven arkitektur förlitar sig främst på asynkron kommunikation. En vanlig utmaning som asynkron kommunikation innebär är felhantering. Ett sätt att lösa det här problemet är att använda en dedikerad felhanterarprocessor.

    När en händelsekonsument stöter på ett fel skickar den omedelbart och asynkront den problematiska händelsen till felhanterarprocessorn och fortsätter att bearbeta andra händelser. Felhanterarprocessorn försöker lösa problemet. Om det lyckas skickas händelsen till den ursprungliga inmatningskanalen igen av felhanterarprocessorn. Om det misslyckas kan processorn vidarebefordra händelsen till en administratör för ytterligare kontroll. När du använder en felhanterarprocessor bearbetas återpublicerade händelser utan sekvens.

  • Dataförlust

    En annan utmaning som asynkron kommunikation innebär är dataförlust. Om någon av komponenterna kraschar innan den bearbetas och överlämnas till nästa komponent tas händelsen bort och når aldrig slutmålet. För att minimera risken för dataförlust bevarar du händelser under överföring och tar bort eller tar bort händelserna endast när nästa komponent bekräftar mottagandet av händelsen. Dessa funktioner kallas klient bekräftar läge och senaste deltagare support.

  • Implementering av ett traditionellt mönster för begärande-svar

    Ibland kräver händelseproducenten ett omedelbart svar från händelsekonsumenten, till exempel att skaffa kundberättigande innan en beställning fortsätter. I en händelsedriven arkitektur kan synkron kommunikation uppnås med hjälp av meddelandehantering med begärandesvar.

    Det här mönstret implementeras med en begärankö och en svarskö. Händelseproducenten skickar en asynkron begäran till en begäranskö, pausar andra åtgärder för den uppgiften och väntar på ett svar i svarskön. Den här metoden omvandlar effektivt det här mönstret till en synkron process. Händelsekonsumenter bearbetar sedan begäran och skickar tillbaka svaret via en svarskö. Den här metoden använder vanligtvis ett sessions-ID för spårning, så händelseproducenten vet vilket meddelande i svarskön som är relaterat till den specifika begäran. Den ursprungliga begäran kan också ange namnet på svarskö, potentiellt tillfällig, i ett svar-till-huvud eller ett annat ömsesidigt överenskommet anpassat attribut.

  • Underhåll av lämpligt antal händelser

    Att generera ett överdrivet antal detaljerade händelser kan mätta och överbelasta systemet. En överdriven mängd händelser gör det svårt att effektivt analysera det övergripande flödet av händelser. Det här problemet förvärras när ändringar måste återställas. Omvänt kan alltför konsoliderande händelser också skapa problem, vilket resulterar i onödig bearbetning och svar från händelsekonsumenter.

    För att uppnå rätt balans bör du överväga konsekvenserna av händelser och om konsumenterna behöver inspektera händelsens nyttolaster för att fastställa deras svar. Om du till exempel har en komponent för efterlevnadskontroll kan det vara tillräckligt att endast publicera två typer av händelser: kompatibla och inkompatibla. Den här metoden hjälper till att säkerställa att endast relevanta konsumenter bearbetar varje händelse, vilket förhindrar onödig bearbetning.

Andra överväganden

  • Mängden data som ska inkluderas i en händelse kan vara en betydande faktor som påverkar prestanda och kostnader. Du kan förenkla bearbetningskoden och eliminera extra sökningar genom att placera all relevant information som behövs för bearbetning direkt i händelsen. När du bara lägger till en minimal mängd information till en händelse, till exempel några identifierare, minskar du transporttiden och kostnaden. Den här metoden kräver dock att bearbetningskoden hämtar eventuell extra information som behövs. Mer information finns i Lägga dina händelser på en diet.

  • En begäran visas endast för komponenten för hantering av begäranden. Men händelser är ofta synliga för flera komponenter i en arbetsbelastning, även om dessa komponenter inte använder dem eller inte är avsedda att använda dem. Tänk på vilken information du tar med i händelser för att förhindra oavsiktlig informationsexponering för att arbeta med ett tänkesätt för "anta intrång".

  • Många program använder händelsedriven arkitektur som primär arkitektur. Du kan kombinera den här metoden med andra arkitekturformat för att skapa en hybridarkitektur. Typiska kombinationer är mikrotjänster och rör och filter. Integrera en händelsedriven arkitektur för att förbättra systemets prestanda genom att eliminera flaskhalsar och ge tillbakatryck under volymer med höga begäranden.

  • Specifika domäner omfattar ofta flera händelseproducenter, konsumenter eller händelsekanaler. Ändringar i en specifik domän kan påverka många komponenter.

Nästa steg