Händelsedrivet arkitekturformat

En händelsedriven arkitektur består av händelseproducenter som genererar en dataström med händelser och händelseförbrukare som lyssnar efter händelserna.

Diagram över ett händelsedrivet arkitekturformat

Händelser levereras nära nog i realtid, så att förbrukarna kan svara omedelbart på händelser när de inträffar. Producenter är frikopplade från konsumenter – en producent vet inte vilka konsumenter som lyssnar. Förbrukarna är också fristående från varandra och varje förbrukare ser alla händelser. Detta skiljer sig från mönstret Konkurrerande förbrukare där förbrukaren hämtar meddelanden från en kö och ett meddelande bearbetas bara en gång (förutsatt att det inte uppstår några fel). I vissa system, t.ex IoT, måste händelser matas in i mycket stora volymer.

En händelsedriven arkitektur kan använda en pub/sub-modell eller en händelseströmsmodell.

  • Pub/sub: Meddelandeinfrastrukturen håller reda på prenumerationerna. När en händelse publiceras skickas händelsen till varje prenumerant. När en händelse har tagits emot, kan den inte återupprepas och nya prenumeranter ser inte händelsen.

  • Händelseströmning: Händelser skrivs till en logg. Händelserna är strikt sorterade (inom en partition) och beständiga. Klienterna prenumererar inte på dataströmmen, utan i stället kan en klient läsa från valfri del av strömmen. Klienten är ansvarig för avancera dess position i dataströmmen. Det innebär att en klient kan ansluta till när som helst och spela upp händelser.

Det finns vissa vanliga varianter på förbrukarsidan:

  • Enkel händelsebearbetning. En händelse utlöser direkt en åtgärd i förbrukaren. Du kan till exempel använda Azure Functions med en Service Bus-utlösare, så att en funktion körs varje gång ett meddelande har publicerats i ett Service Bus-ämne.

  • Komplex händelsebearbetning. En förbrukare bearbetar en serie händelser och söker efter mönster i data med en teknik som till exempel Azure Stream Analytics eller Apache Storm. Du kan exempelvis aggregera värdena från en inbäddad enhet via ett tidsfönster och generera en avisering om glidande medelvärde överskrider ett visst tröskelvärde.

  • Händelseströmbearbetning. Använd en dataströmningsplattform, till exempel Azure IoT Hub eller Apache Kafka, som en pipeline för att mata in händelser och mata dem till strömprocessorer. Strömprocessorerna fungerar så att de behandlar eller transformerar dataströmmen. Det kan finnas flera strömprocessorer för olika delsystem av programmet. Den här metoden passar bra för IoT-arbetsbelastningar.

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

I den logiska diagrammet ovan för visas varje typ av konsument som en enda ruta. I praktiken är det vanligt att ha flera instanser av en förbrukare för att undvika att förbrukaren blir en felkritisk systemdel. Flera instanser kan också krävas för att hantera händelsernas volym och frekvens. En enskild förbrukare kan också bearbeta händelser i flera trådar. Detta kan skapa utmaningar om händelser måste bearbetas i ordning eller kräver exakt en gång-semantik. Se Minimera samordning.

När ska den här arkitekturen användas?

  • Flera delsystem måste bearbeta samma händelser.
  • Realtidsbearbetning med minsta tidsförskjutning.
  • Komplex händelsebearbetning, till exempel mönstermatchning eller aggregering över tidsfönster.
  • Hög volym och datahastighet, till exempel IoT.

Fördelar

  • Producenter och förbrukare är fristående.
  • Inga punkt-till-punkt-integreringar. Det är lätt att lägga till nya förbrukare i systemet.
  • Förbrukarna kan reagera på händelser direkt när de tas emot.
  • Stora skalbarhets- och distributionsmöjligheter.
  • Delsystem har fristående vyer över händelseströmmen.

Utmaningar

  • Garanterad leverans. Det är viktigt att säkerställa att händelser levereras i en del system, särskilt i IoT-scenarier.
  • Bearbetning av händelser i tur och ordning eller bara en gång. Varje typ av förbrukare körs vanligtvis i flera instanser för flexibilitet och skalbarhet. Detta kan medföra utmaningar om händelserna måste bearbetas i ordning (inom en förbrukartyp), eller om standardbearbetningslogiken inte är idempotent.

Annat som är bra att tänka på

  • Mängden data som ska inkluderas i en händelse kan vara en viktig faktor som påverkar både prestanda och kostnad. Att lägga till all relevant information som behövs för bearbetning i själva händelsen kan förenkla bearbetningskoden och spara ytterligare uppslag. Att placera den minimala mängden information i en händelse, precis som ett par identifierare, minskar transporttiden och kostnaden, men kräver att bearbetningskoden söker upp eventuell ytterligare information som behövs. Mer information om detta finns i det här blogginlägget.