Bewerken

Delen via


Gebeurtenisafhankelijke architectuurstijl

Azure Stream Analytics
Azure Functions
Azure Service Bus

Een gebeurtenisgestuurde architectuur bestaat uit gebeurtenisproducenten die een stroom gebeurtenissen genereren, gebeurtenisgebruikers die naar deze gebeurtenissen luisteren en gebeurteniskanalen die gebeurtenissen overdragen van producenten naar consumenten.

Diagram van een gebeurtenisgestuurde architectuurstijl

Gebeurtenissen worden vrijwel realtime afgeleverd, zodat consumers onmiddellijk op de gebeurtenissen kunnen reageren. Producenten worden losgekoppeld van consumenten: een producent weet niet welke consumenten luisteren. Consumers zijn ook ontkoppeld van elkaar en elke consumer ziet alle gebeurtenissen. Dit wijkt af van een patroon met concurrerende consumers, waarbij consumers berichten uit een wachtrij halen en een bericht slechts één keer wordt verwerkt (ervan uitgaande dat er geen fouten worden gemaakt). In sommige systemen, zoals IoT, moeten gebeurtenissen bij zeer hoge volumes worden ingenomen.

Een gebeurtenisgestuurde architectuur kan een publiceren/abonneren-model (ook wel pub/sub genoemd) of een gebeurtenisstroommodel gebruiken.

  • Pub/sub: De berichteninfrastructuur houdt abonnementen bij. Wanneer een gebeurtenis wordt gepubliceerd, wordt de gebeurtenis verzonden naar elk abonnee. Nadat een gebeurtenis is ontvangen, kan deze niet opnieuw worden afgespeeld en zien nieuwe abonnees de gebeurtenis niet.

  • Gebeurtenissen streamen: gebeurtenissen worden naar een logboek geschreven. Gebeurtenissen zijn strikt geordend (binnen een partitie) en duurzaam. Clients abonneren zich niet op de stroom; in plaats daarvan kan een client een deel van de stroom lezen. De client is ervoor verantwoordelijk de positie in de stroom naar voren te halen. Dit betekent dat een client op elk gewenst moment kan deelnemen en gebeurtenissen opnieuw kan afspelen.

Consumers kennen een aantal veelvoorkomende variaties:

  • Verwerking van eenvoudige gebeurtenissen. Een gebeurtenis activeert onmiddellijk een actie in de consumer. U kunt bijvoorbeeld Azure Functions gebruiken met een Service Bus-trigger, zodat een functie wordt uitgevoerd zodra een bericht in een Service Bus-onderwerp wordt gepubliceerd.

  • Correlatie van basis gebeurtenis. Een consument moet een klein aantal discrete bedrijfsgebeurtenissen verwerken, meestal gecorreleerd door een bepaalde id, waarbij bepaalde informatie van eerdere gebeurtenissen moet worden bewaard die moeten worden gebruikt bij het verwerken van latere gebeurtenissen. Dit patroon wordt ondersteund door bibliotheken zoals NServiceBus en MassTransit.

  • Verwerken van complexe gebeurtenissen. Een consument verwerkt een reeks gebeurtenissen, op zoek naar patronen in de gebeurtenisgegevens, met behulp van een technologie zoals Azure Stream Analytics. U kunt bijvoorbeeld uitlezingen van een ingesloten apparaat gedurende een bepaalde periode aggregeren en een melding genereren als het zwevend gemiddelde een zekere drempelwaarde overschrijdt.

  • Verwerken van gebeurtenisstromen. Gebruik een platform voor gegevensstromen, zoals Azure IoT Hub of Apache Kafka, als een pijplijn om gebeurtenissen op te nemen en ze naar streamprocessors door te leiden. De streamprocessors verwerken of transformeren de stroom. Er kunnen meerdere streamprocessors zijn voor verschillende subsystemen van de toepassing. Deze benadering is zeer geschikt voor IoT-werkbelastingen.

De bron van de gebeurtenissen kan extern zijn, zoals fysieke apparaten in een IoT-oplossing. In dat geval moet het systeem in staat zijn de gegevens op te nemen bij een volume en doorvoer die door de gegevensbron wordt vereist.

Er zijn twee primaire benaderingen voor het structureren van nettoladingen van gebeurtenissen. Wanneer u controle hebt over uw gebeurtenisconsumenten, neemt u deze beslissing over de nettoladingstructuur per consument; het combineren van benaderingen indien nodig binnen één workload.

  • Inclusief alle vereiste kenmerken in de nettolading: deze benadering wordt gebruikt wanneer u wilt dat consumenten alle beschikbare informatie hebben zonder dat ze een query hoeven uit te voeren op een externe gegevensbron. Het kan echter leiden tot problemen met gegevensconsistentie vanwege meerdere recordsystemen, met name na updates. Contractbeheer en versiebeheer kunnen ook complex worden.

  • Alleen sleutel(s) opnemen in de nettolading: bij deze benadering halen consumenten de benodigde kenmerken, zoals een primaire sleutel, op om de resterende gegevens onafhankelijk van een gegevensbron op te halen. Hoewel deze methode betere gegevensconsistentie biedt vanwege één recordsysteem, kan deze slechter presteren dan de eerste benadering, omdat consumenten regelmatig een query moeten uitvoeren op de gegevensbron. Er zijn minder problemen met betrekking tot koppeling, bandbreedte, contractbeheer of versiebeheer, omdat gebeurtenissen kleiner zijn en contracten eenvoudiger zijn.

In het bovenstaande logische diagram wordt elk type consumer als een vak weergegeven. In de praktijk zijn vaak meerdere exemplaren van een consumer aanwezig om te voorkomen dat de consumer een Single Point of Failure wordt. Er kunnen ook meerdere exemplaren nodig zijn om het volume en de frequentie van gebeurtenissen te verwerken. Ook kan één consumer gebeurtenissen voor meerdere threads verwerken. Dit kan uitdagingen opleveren als gebeurtenissen op volgorde moeten worden verwerkt of exact één keer semantiek moeten zijn vereist. Zie Coördinatie minimaliseren.

Er zijn twee primaire topologieën binnen veel gebeurtenisgestuurde architecturen:

  • Brokertopologie. Onderdelen zenden gebeurtenissen uit als gebeurtenissen aan het hele systeem en andere onderdelen reageren op de gebeurtenis of negeren de gebeurtenis. Deze topologie is handig wanneer de stroom voor gebeurtenisverwerking relatief eenvoudig is. Er is geen centrale coördinatie of indeling, dus deze topologie kan zeer dynamisch zijn. Deze topologie is sterk ontkoppeld, wat helpt schaalbaarheid, reactiesnelheid en fouttolerantie voor onderdelen te bieden. Er is geen onderdeel eigenaar van of is op de hoogte van de status van een multistep-bedrijfstransactie en acties worden asynchroon uitgevoerd. Vervolgens zijn gedistribueerde transacties riskant omdat er geen systeemeigen middelen zijn om opnieuw te worden opgestart of opnieuw worden afgespeeld. Foutafhandeling en handmatige interventiestrategieën moeten zorgvuldig worden overwogen omdat deze topologie een bron van inconsistentie van gegevens kan zijn.

  • Bemiddelaartopologie. Deze topologie behandelt enkele van de tekortkomingen van de brokertopologie. Er is een gebeurtenisbemiddelaar die de stroom van gebeurtenissen beheert en beheert. De gebeurtenisbemiddelaar onderhoudt de status en beheert foutafhandeling en herstartmogelijkheden. In tegenstelling tot brokertopologie uitzenden onderdelen exemplaren als opdrachten en alleen naar aangewezen kanalen, meestal berichtenwachtrijen. Deze opdrachten worden naar verwachting niet genegeerd door hun gebruikers. Deze topologie biedt meer controle, betere gedistribueerde foutafhandeling en mogelijk betere gegevensconsistentie. Deze topologie introduceert een verhoogde koppeling tussen onderdelen en de gebeurtenisbemiddelaar kan een knelpunt of een betrouwbaarheidsprobleem worden.

Wanneer gebruikt u deze architectuur?

  • Meerdere subsystemen moeten dezelfde gebeurtenissen verwerken.
  • Realtime verwerking met een minimum aan tijdsverlies.
  • Verwerking van complexe gebeurtenissen, zoals patroonvergelijking of aggregatie binnen bepaalde tijdvensters.
  • Gegevens van hoog volume en met hoge snelheid, zoals IoT.

Vergoedingen

  • Producers en consumers worden ontkoppeld.
  • Geen punt-naar-punt-integraties. Het is eenvoudig nieuwe gebruikers aan het systeem toe te voegen.
  • Consumers kunnen onmiddellijk reageren op gebeurtenissen zodra ze binnenkomen.
  • Zeer schaalbaar, elastisch en gedistribueerd.
  • Subsystemen hebben onafhankelijke weergaven van de gebeurtenisstroom.

Uitdagingen

  • Gegarandeerde levering.

    In sommige systemen, met name in IoT-scenario's, is het essentieel dat gebeurtenissen worden geleverd.

  • Verwerking van gebeurtenissen op volgorde of slechts één keer.

    Elk type consumer wordt gewoonlijk uitgevoerd in meerdere exemplaren, voor tolerantie en schaalbaarheid. Dit kan een uitdaging creëren als de gebeurtenissen op volgorde moeten worden verwerkt (binnen een consumententype) of idempotent berichtverwerkingslogica niet is geïmplementeerd.

  • Berichten in verschillende services coördineren.

    Bedrijfsprocessen omvatten vaak meerdere services die publiceren en abonneren op berichten om een consistent resultaat te bereiken voor een hele workload. Werkstroompatronen zoals het choreograafpatroon en Saga Orchestration kunnen worden gebruikt om berichtstromen over verschillende services betrouwbaar te beheren.

  • Foutafhandeling.

    Gebeurtenisgestuurde architectuur maakt voornamelijk gebruik van asynchrone communicatie. Een uitdaging met asynchrone communicatie is foutafhandeling. Een manier om dit probleem op te lossen is door een afzonderlijke processor voor fouthandlers te gebruiken. Dus wanneer de gebruiker van de gebeurtenis een fout ondervindt, wordt deze onmiddellijk en asynchroon de foutieve gebeurtenis naar de processor van de fout-handler verzonden en verplaatst. De fout-handlerprocessor probeert de fout op te lossen en stuurt de gebeurtenis terug naar het oorspronkelijke opnamekanaal. Maar als de fout-handlerprocessor mislukt, kan de foutieve gebeurtenis worden verzonden naar een beheerder voor verdere inspectie. Als u een fout-handlerprocessor gebruikt, worden foutieve gebeurtenissen niet op volgorde verwerkt wanneer ze opnieuw worden verzonden.

  • Gegevensverlies.

    Een andere uitdaging met asynchrone communicatie is gegevensverlies. Als een van de onderdelen vastloopt voordat de gebeurtenis is verwerkt en aan het volgende onderdeel wordt overgedragen, wordt de gebeurtenis verwijderd en wordt deze nooit naar de uiteindelijke bestemming gebracht. Als u de kans op gegevensverlies wilt minimaliseren, moet u gebeurtenissen in transit behouden en de gebeurtenissen alleen verwijderen of verwijderen wanneer het volgende onderdeel de ontvangst van de gebeurtenis heeft bevestigd. Deze functies worden meestal de clientbevestigingsmodus en de laatste ondersteuning van deelnemers genoemd.

  • Het implementeren van een traditioneel aanvraag-antwoordpatroon.

    Soms vereist de gebeurtenisproducent een onmiddellijke reactie van de gebeurtenisconsumer, zoals het verkrijgen van een klant waarvoor een klant in aanmerking komt voordat deze doorgaat met een bestelling. In gebeurtenisgestuurde architectuur kan synchrone communicatie worden bereikt via berichtgeving voor aanvragen en antwoorden.

    Dit patroon wordt meestal geïmplementeerd door gebruik te maken van meerdere wachtrijen: een aanvraagwachtrij en een antwoordwachtrij. De gebeurtenisproducent verzendt een asynchrone aanvraag naar een aanvraagwachtrij, onderbreekt andere bewerkingen voor die taak en wacht op een antwoord in de antwoordwachtrij; dit effectief omzetten in een synchroon proces. Gebeurtenisgebruikers verwerken vervolgens de aanvraag en sturen het antwoord terug via een antwoordwachtrij. Deze benadering maakt meestal gebruik van een sessie-id voor het bijhouden, zodat de gebeurtenisproducent weet welk bericht in de antwoordwachtrij is gerelateerd aan de specifieke aanvraag. De oorspronkelijke aanvraag kan ook de naam van de antwoordwachtrij opgeven, mogelijk kortstondig, in een antwoordheader of een ander wederzijds overeengekomen aangepast kenmerk.

  • Het juiste aantal gebeurtenissen onderhouden.

    Het genereren van een overmatig aantal fijnmazige gebeurtenissen kan het systeem overbelasten en overweldigen, waardoor het moeilijk is om de algehele stroom van gebeurtenissen effectief te analyseren. Dit probleem wordt verergerd wanneer wijzigingen moeten worden teruggedraaid. Omgekeerd kunnen over het consolideren van gebeurtenissen ook problemen veroorzaken, wat resulteert in onnodige verwerking en reacties van gebeurtenisgebruikers.

    Als u het juiste evenwicht wilt bereiken, moet u rekening houden met de gevolgen van gebeurtenissen en of consumenten de nettoladingen van gebeurtenissen moeten inspecteren om hun reacties te bepalen. Als u bijvoorbeeld een onderdeel voor nalevingscontrole hebt, kan het voldoende zijn om slechts twee typen gebeurtenissen te publiceren: compatibel en niet-compatibel. Met deze aanpak kan elke gebeurtenis alleen worden verwerkt door relevante consumenten, waardoor onnodige verwerking wordt voorkomen.

Aanvullende overwegingen

  • De hoeveelheid gegevens die in een gebeurtenis moet worden opgenomen, kan een belangrijke overweging zijn die van invloed is op zowel prestaties als kosten. Door alle relevante informatie die nodig is voor verwerking in het evenement zelf te plaatsen, kan de verwerkingscode worden vereenvoudigd en extra zoekacties worden opgeslagen. Als u de minimale hoeveelheid informatie in een gebeurtenis plaatst, zoals slechts een paar id's, vermindert u de transporttijd en kosten, maar vereist de verwerkingscode om aanvullende informatie op te zoeken die nodig is. Bekijk dit blogbericht voor meer informatie hierover.
  • Hoewel een aanvraag alleen zichtbaar is voor het onderdeel voor het verwerken van aanvragen, zijn gebeurtenissen vaak zichtbaar voor meerdere onderdelen in een workload, zelfs als deze onderdelen niet of niet bedoeld zijn om ze te gebruiken. Houd rekening met de informatie die u in gebeurtenissen opneemt om onbedoelde blootstelling aan informatie te voorkomen.
  • Veel toepassingen gebruiken gebeurtenisgestuurde architectuur als hun primaire architectuur; Deze benadering kan echter worden gecombineerd met andere architectuurstijlen, wat resulteert in hybride architecturen. Algemene combinaties zijn microservices en pijpen en filters. De integratie van gebeurtenisgestuurde architectuur verbetert de systeemprestaties door knelpunten te elimineren en backdruk te bieden tijdens grote aanvraagvolumes.
  • Specifieke domeinen omvatten vaak meerdere gebeurtenisproducenten, consumenten of gebeurteniskanalen. Wijzigingen in een bepaald domein kunnen van invloed zijn op veel onderdelen.