Betrouwbare gebeurtenisverwerking met Azure Functions en Event Hubs

Leer hoe je robuuste, betrouwbare serverless oplossingen bouwt door Azure Functions te gebruiken met Azure Event Hubs-triggers. Dit artikel behandelt best practices voor checkpoints, foutafhandeling en het implementeren van circuit breaker-patronen om ervoor te zorgen dat je geen gebeurtenissen verliest en je event-gedreven applicaties stabiel en veerkrachtig blijven.

Uitdagingen van gebeurtenisstromen in gedistribueerde systemen

Overweeg een systeem waarmee gebeurtenissen met een constante snelheid van 100 gebeurtenissen per seconde worden verzonden. Bij deze snelheid kunnen meerdere parallelle instanties 100 binnenkomende gebeurtenissen per seconde verwerken.

Houd echter rekening met deze uitdagingen voor het consumeren van een gebeurtenisstroom.

  • Een event publisher verstuurt een corrupte gebeurtenis.
  • Uw functiecode ondervindt een niet-verwerkte uitzondering.
  • Een downstreamsysteem gaat offline en blokkeert de verwerking van gebeurtenissen.

In tegenstelling tot een Azure Queue Storage-trigger, die berichten tijdens de verwerking vergrendelt, leest Azure Event Hubs per partitie vanaf een enkel punt in de stream. Dit leesgedrag, dat meer lijkt op een videospeler, biedt de gewenste voordelen van hoge doorvoer, meerdere consumentengroepen en mogelijkheden voor opnieuw afspelen. Gebeurtenissen worden gelezen, vooruit of achteruit, vanaf een controlepunt, maar u moet de aanwijzer verplaatsen om nieuwe gebeurtenissen te verwerken. Zie Controlepunt in de Documentatie van Event Hubs voor meer informatie.

Wanneer er fouten optreden in een stream en u ervoor kiest om de aanwijzer niet door te voeren, wordt verdere verwerking van gebeurtenissen geblokkeerd. Met andere woorden, als je de pointer stopt om een probleem op te lossen bij het verwerken van een enkele gebeurtenis, beginnen de onverwerkte gebeurtenissen zich op te stapelen.

Functie voorkomt impasses door de aanwijzer van de stream altijd te verplaatsen, ongeacht succes of mislukking. Omdat de aanwijzer steeds verdergaat, moeten uw functies op de juiste wijze omgaan met fouten.

Hoe de Event Hubs-trigger gebeurtenissen verbruikt

Azure Functions verwerkt gebeurtenissen van een Event Hub door de volgende stappen uit te voeren.

  1. De trigger maakt een pointer aan en bewaart deze in Azure Storage voor elke partitie van de event hub.
  2. De trigger ontvangt standaard nieuwe gebeurtenissen in een batch, en de host probeert de functie te triggeren, waardoor de batch van gebeurtenissen wordt geleverd voor de verwerking.
  3. Wanneer de uitvoering van de functie voltooid is, met of zonder uitzonderingen, verplaatst de trigger de pointer en slaat een checkpoint op naar het standaard hostgeheugenaccount.
  4. Als voorwaarden voorkomen dat de uitvoering van de functie wordt voltooid, kan de host de pointer niet laten doorgaan. Wanneer de aanwijzer niet verder kan gaan, worden dezelfde gebeurtenissen opnieuw verwerkt.

Dit gedrag toont enkele belangrijke punten:

  • Niet-verwerkte uitzonderingen kunnen ertoe leiden dat u gebeurtenissen kwijtraakt:

    Functies die een uitzondering genereren, gaan verder met het verplaatsen van de aanwijzer. Als u een beleid voor opnieuw proberen of andere logica voor opnieuw proberen instelt, wordt de aanwijzer vertraagd totdat het hele opnieuw proberen is voltooid.

  • Functions garandeert ten minste eenmaal levering:

    Uw code en afhankelijke systemen moeten mogelijk rekening houden met het feit dat dezelfde gebeurtenis tweemaal kan worden verwerkt. Voor meer informatie, zie Het ontwerpen van Azure Functions voor identieke invoer.

  • Checkpoint state wordt opgeslagen in Azure Storage:

    De trigger slaat het checkpoint (verwerkingsaanwijzer) op in het opslagaccount dat via de instelling AzureWebJobsStorage van de functie-app is geconfigureerd. Deze verwijzing naar een opgeslagen checkpoint betekent:

    • Wanneer je overschakelt AzureWebJobsStorage naar een ander opslagaccount, begint de functie met verwerken vanaf een nieuwe positie, wat kan resulteren in het opnieuw verwerken van gebeurtenissen.
    • Wanneer een event hub wordt verwijderd en opnieuw aangemaakt, wordt de positie van de gebeurtenisstroom (zoals sequentienummers en offsets) gereset, terwijl opgeslagen checkpointreferenties ongewijzigd blijven. In dit scenario verwerkt de functie mogelijk geen nieuwe gebeurtenissen totdat het checkpoint handmatig is verwijderd.

Afhandeling van uitzonderingen

Hoewel alle functiecode een try/catch-blok op het hoogste codeniveau moet bevatten, is het nog belangrijker om een catch blok te hebben voor functies die Event Hubs-gebeurtenissen verbruiken. Wanneer er een uitzondering optreedt, behandelt het catch-blok de fout voordat de pointer verder gaat.

Mechanismen en beleidsregels voor opnieuw proberen

Omdat veel uitzonderingen in de cloud tijdelijk zijn, is de eerste stap in foutafhandeling altijd om de bewerking opnieuw uit te voeren. U kunt ingebouwd beleid voor opnieuw proberen toepassen of uw eigen logica voor opnieuw proberen definiëren.

Beleid opnieuw proberen

Functions biedt ingebouwd beleid voor opnieuw proberen voor Event Hubs. Bij het gebruik van herkansingsbeleid genereer je simpelweg een nieuwe uitzondering en probeert de host het evenement opnieuw te verwerken op basis van het gedefinieerde beleid. Voor dit gedrag van opnieuw proberen is versie 5.x of later van de Event Hubs-extensie vereist. Zie Beleid voor opnieuw proberen voor meer informatie.

Aangepaste logica voor opnieuw proberen

U kunt ook uw eigen logica voor opnieuw proberen definiëren in de functie zelf. U kunt bijvoorbeeld een beleid implementeren dat volgt op een werkstroom die wordt geïllustreerd door de volgende regels:

  • Probeer een gebeurtenis drie keer te verwerken (mogelijk met een vertraging tussen nieuwe pogingen).
  • Als het uiteindelijke resultaat van alle nieuwe pogingen een fout is, voegt u een gebeurtenis toe aan een wachtrij, zodat de verwerking kan doorgaan in de stream.
  • Beschadigde of niet-verwerkte gebeurtenissen worden later verwerkt.

Opmerking

Polly is een voorbeeld van een tolerantie- en tijdelijke foutafhandelingsbibliotheek voor C#-toepassingen.

Niet-uitzonderingsfouten

Sommige problemen kunnen optreden zonder dat er een uitzondering wordt gegenereerd. Denk bijvoorbeeld aan een geval waarin een aanvraag een time-out krijgt of wanneer de instantie waarop de functie wordt uitgevoerd vastloopt. Wanneer een functie niet kan worden voltooid zonder uitzondering, wordt de offsetaanwijzer nooit geavanceerd. Als de aanwijzer niet verder gaat, blijft een instantie na een mislukte uitvoering dezelfde gebeurtenissen lezen. Deze situatie biedt een garantie van ten minste één keer .

De zekerheid dat elke gebeurtenis ten minste één keer wordt verwerkt, impliceert dat sommige gebeurtenissen meer dan één keer kunnen worden verwerkt. Uw functie-apps moeten zich bewust zijn van deze mogelijkheid en moeten worden gebouwd rond de principes van idempotentie.

Foutstatussen verwerken

Uw app kan mogelijk een aantal fouten in gebeurtenisverwerking acceptabel verwerken. U moet echter ook voorbereid zijn op het afhandelen van de permanente foutstatus, die kan optreden als gevolg van fouten in downstreamverwerking. In een dergelijke foutstatus, zoals wanneer een downstreamgegevensopslag offline is, moet uw functie stoppen met het activeren van gebeurtenissen totdat het systeem in een gezonde toestand is.

Circuitonderbrekerpatroon

Wanneer u het circuitonderbrekerpatroon implementeert, kan uw app de verwerking van gebeurtenissen effectief onderbreken en op een later tijdstip hervatten nadat problemen zijn opgelost.

Er zijn twee onderdelen vereist voor het implementeren van een circuitonderbreker in een gebeurtenisstroomproces:

  • Gedeelde status voor alle exemplaren om de status van het circuit bij te houden en te bewaken.
  • Een primair proces dat de circuitstatus kan beheren, als open of closed.

Implementatiedetails kunnen variëren, maar om de status te delen tussen exemplaren hebt u een opslagmechanisme nodig. U kunt de status opslaan in Azure Storage, een Redis-cache of een andere permanente service die toegankelijk is voor uw functie-app-exemplaren.

Zowel Durable Functions als Azure Logic Apps bieden infrastructuur voor het beheren van werkstromen en circuitstatussen. In dit artikel wordt beschreven hoe u Logic Apps gebruikt om de uitvoering van functies te onderbreken en opnieuw op te starten, zodat u de controle hebt die nodig is om het circuitonderbrekerpatroon te implementeren.

Een foutendrempel voor alle exemplaren definiëren

Permanente gedeelde externe status is vereist om de status van het circuit te bewaken wanneer meerdere exemplaren gelijktijdig gebeurtenissen verwerken. Vervolgens kunt u deze persistente status bewaken op basis van regels die een foutstatus aangeven, zoals:

Als er meer dan 100 gebeurtenisfouten zijn binnen een periode van 30 seconden bij alle toepassingen, onderbreek dan het circuit om te stoppen met het activeren van nieuwe gebeurtenissen.

De implementatiedetails voor deze bewakingslogica variëren, afhankelijk van uw specifieke app-behoeften, maar in het algemeen moet u een systeem maken dat:

  1. Registreert fouten bij persistente opslag.
  2. Controleer het doorlopend aantal wanneer nieuwe fouten worden geregistreerd om te bepalen of de drempelwaarde voor gebeurtenisfouten wordt bereikt.
  3. Wanneer aan deze drempelwaarde wordt voldaan, verzendt u een gebeurtenis die aangeeft dat het systeem het circuit moet verbreken.

Circuitstatus beheren met Azure Logic Apps

Azure Logic Apps bevat ingebouwde connectors naar verschillende services, functies en stateful orchestrations. Het is een logische keuze om circuit-toestand te beheren. Nadat u hebt gedetecteerd wanneer een circuit moet worden onderbroken, kunt u een logische app bouwen om deze werkstroom te implementeren:

  1. Activeer een Event Grid-werkstroom die de verwerking van de functie stopt.
  2. Verzend een e-mailmelding met een optie om de werkstroom opnieuw op te starten.

Om te leren hoe je specifieke functies kunt uit- en weer inschakelen met behulp van app-instellingen, zie Hoe je functies uitschakelt in Azure Functions.

De ontvanger van de e-mail kan de gezondheid van het circuit onderzoeken en, indien passend, het circuit opnieuw starten via een link in de meldingsmail. Wanneer de workflow de functie opnieuw opstart, verwerkt de functie gebeurtenissen vanaf het laatste controlepunt van de Event Hub.

Als je deze aanpak gebruikt, verlies je geen gebeurtenissen, verwerk je gebeurtenissen in volgorde en kun je het circuit zo lang breken als nodig is.

Migratiestrategieën voor Event Grid-triggers

Wanneer u een bestaande functie-app migreert tussen regio's of tussen sommige plannen, moet u de app opnieuw maken tijdens het migratieproces. In dit geval heb je tijdens het migratieproces mogelijk twee apps die beide van dezelfde gebeurtenisstroom kunnen consumeren en naar dezelfde uitvoerbestemming kunnen schrijven.

Om verlies of duplicatie van gebeurtenisgegevens tijdens het migratieproces te voorkomen, overweeg gebruik te maken van consumentengroepen:

  1. Maak een nieuwe consumentengroep voor de nieuwe doel-app.

  2. Configureer de trigger in de nieuwe app om deze nieuwe consumentengroep te gebruiken.

    Door deze aanpak te gebruiken, kunnen beide apps gebeurtenissen onafhankelijk verwerken tijdens de validatie.

  3. Controleer of de nieuwe app gebeurtenissen correct verwerkt.

  4. Stop de originele app of verwijder het abonnement of de gebruikersgroep.