Dela via


Design för elastiska händelsehubbar och funktioner

Felhantering, design för idempotens och hantering av återförsöksbeteende är några av de viktiga åtgärder som du kan vidta för att säkerställa att event hubs-utlösta funktioner är motståndskraftiga och kan hantera stora mängder data. Den här artikeln beskriver dessa viktiga begrepp och ger rekommendationer för serverlösa lösningar för händelseströmning.

Azure tillhandahåller tre huvudsakliga meddelandetjänster som kan användas med Azure Functions för att stödja en mängd olika unika, händelsedrivna scenarier. På grund av den partitionerade konsumentmodellen och möjligheten att mata in data med hög hastighet används Azure Event Hubs ofta för händelseströmning och stordatascenarier. En detaljerad jämförelse av Azure-meddelandetjänster finns i Välj mellan Azure-meddelandetjänster – Event Grid, Event Hubs och Service Bus.

Strömningsfördelar och utmaningar

Att förstå fördelarna och nackdelarna med strömmar hjälper dig att uppskatta hur en tjänst som Event Hubs fungerar. Du behöver också den här kontexten när du fattar viktiga arkitektoniska beslut, felsöker problem och optimerar prestanda. Överväg följande viktiga begrepp om lösningar med både Event Hubs och Functions:

  • Strömmar är inte köer: Event Hubs, Kafka och andra liknande erbjudanden som bygger på den partitionerade konsumentmodellen stöder inte i sig några av huvudfunktionerna i en meddelandekö som Service Bus. Den kanske största indikatorn på dessa skillnader är det faktum att läsningar är icke-destruktiva. Detta säkerställer att data som läse av Functions-värden förblir tillgängliga efteråt. I stället är meddelanden oföränderliga och förblir för andra konsumenter att läsa, inklusive potentiellt samma konsument som läser det igen. Därför kan lösningar som implementerar mönster som konkurrerande konsumenter få bättre service med en meddelandekö som Service Bus.

  • Stöd för inbyggda obeställbara meddelanden saknas: En kanal med obeställbara meddelanden är inte en intern funktion i Event Hubs eller Kafka. Ofta integreras begreppet obeställbara bokstäver i en strömningslösning för att ta hänsyn till data som inte kan bearbetas. Den här funktionen är avsiktligt inte ett medfödd element i Event Hubs och läggs bara till på konsumentsidan för att tillverka ett liknande beteende eller en liknande effekt. Om du behöver stöd för obeställbara meddelanden bör du eventuellt granska ditt val av en meddelandetjänst för direktuppspelning.

  • En arbetsenhet är en partition: I en traditionell meddelandekö är en arbetsenhet ett enda meddelande. I en strömningslösning betraktas en partition ofta som en arbetsenhet. Om varje händelse i en händelsehubb behandlas som ett distinkt meddelande som kräver orderbearbetning eller hantering av finansiella transaktioner, föreslår det en möjlighet att utforska en lämpligare meddelandetjänst för optimal prestanda eller bearbetning.

  • Ingen filtrering på serversidan: En av anledningarna till att Event Hubs kan hantera enorm skala och dataflöde beror på den låga belastningen på själva tjänsten. Funktioner som filtrering på serversidan, index och koordinering mellan mäklare ingår inte i arkitekturen i Event Hubs. Funktioner används ibland för att filtrera händelser genom att dirigera dem till andra händelsehubbar baserat på innehållet i brödtexten eller huvudet. Den här metoden är vanlig i händelseströmning men kommer med förbehållet att den första funktionen läser och utvärderar varje händelse.

  • Alla läsare måste läsa alla data: Eftersom filtrering på serversidan inte är tillgänglig läser en konsument sekventiellt alla data i en partition. Detta omfattar data som kanske inte är relevanta eller till och med kan vara felaktiga. Flera alternativ och strategier kan användas för att kompensera för dessa utmaningar, som beskrivs senare i det här avsnittet.

Dessa viktiga designbeslut gör det möjligt för Event Hubs att göra det som är bäst: stödja en betydande tillströmning av händelser och tillhandahålla en robust och elastisk tjänst som konsumenterna kan läsa från. Varje konsumentprogram har till uppgift att underhålla sina egna förskjutningar på klientsidan eller markören för dessa händelser. De låga kostnaderna gör Event Hubs till ett prisvärt och kraftfullt alternativ för händelseströmning.

Idempotens

En av grundsatserna i Azure Event Hubs är begreppet leverans minst en gång. Den här metoden säkerställer att händelser alltid levereras. Det innebär också att händelser kan tas emot mer än en gång, till och med upprepade gånger, av konsumenter, till exempel en funktion. Därför är det viktigt att en händelsehubbutlöst funktion stöder idempotent-konsumentmönstret .

Att arbeta under antagandet om leverans minst en gång, särskilt inom ramen för en händelsedriven arkitektur, är en ansvarsfull metod för tillförlitlig bearbetning av händelser. Funktionen måste vara idempotent så att resultatet av bearbetningen av samma händelse flera gånger är detsamma som att bearbeta den en gång.

Duplicerade händelser

Det finns flera olika scenarier som kan leda till att dubbletthändelser levereras till en funktion:

  • Kontrollpunkter: Om Azure Functions-värden kraschar eller tröskelvärdet för batchkontrollpunktsfrekvensen inte uppfylls skapas ingen kontrollpunkt. Därför är förskjutningen för konsumenten inte avancerad och nästa gång funktionen anropas återupptas den från den senaste kontrollpunkten. Det är viktigt att observera att kontrollpunkter sker på partitionsnivå för varje konsument.

  • Dubbletthändelser publicerade: Många tekniker kan minska risken för att samma händelse publiceras till en dataström, men konsumenten ansvarar fortfarande för att hantera dubbletter idempotently.

  • Saknade bekräftelser: I vissa situationer kan en utgående begäran till en tjänst lyckas, men en bekräftelse (ACK) från tjänsten tas aldrig emot. Den här uppfattningen kan leda till att det utgående anropet misslyckades och initiera en serie återförsök eller andra resultat från funktionen. I slutändan kan dubbletter av händelser publiceras eller så skapas ingen kontrollpunkt.

Dedupliceringstekniker

Att utforma dina funktioner för identiska indata bör vara standardmetoden som används när du parkopplas med Event Hub-utlösarbindningen. Du bör överväga följande tekniker:

  • Letar efter dubbletter: Innan du bearbetar bör du vidta nödvändiga åtgärder för att verifiera att händelsen ska bearbetas. I vissa fall kräver detta en undersökning för att bekräfta att den fortfarande är giltig. Det kan också vara möjligt att hanteringen av händelsen inte längre behövs på grund av datas färskhet eller logik som ogiltigförklarar händelsen.

  • Designhändelser för idempotens: Genom att tillhandahålla ytterligare information inom nyttolasten för händelsen är det möjligt att se till att bearbetningen flera gånger inte har några skadliga effekter. Ta exemplet med en händelse som innehåller ett belopp för uttag från ett bankkonto. Om det inte hanteras på ett ansvarsfullt sätt är det möjligt att det kan minska saldot för ett konto flera gånger. Men om samma händelse innehåller det uppdaterade saldot till kontot kan det användas för att utföra en upsert-åtgärd till bankkontosaldot. Denna metod för överföring av händelseförd stat kräver ibland samordning mellan producenter och konsumenter och bör användas när det är meningsfullt för deltagande tjänster.

Felhantering och återförsök

Felhantering och återförsök är några av de viktigaste egenskaperna för distribuerade, händelsedrivna program och Funktioner är inget undantag. För händelseströmningslösningar är behovet av korrekt stöd för felhantering avgörande, eftersom tusentals händelser snabbt kan förvandlas till lika många fel om de inte hanteras korrekt.

Vägledning för felhantering

Utan felhantering kan det vara svårt att implementera återförsök, identifiera körningsundantag och undersöka problem. Varje funktion bör ha minst någon nivå eller felhantering. Några rekommenderade riktlinjer är:

  • Använd Application Insights: Aktivera och använd Application Insights för att logga fel och övervaka hälsotillståndet för dina funktioner. Tänk på de konfigurerbara samplingsalternativen för scenarier som bearbetar en stor mängd händelser.

  • Lägg till strukturerad felhantering: Använd lämpliga felhanteringskonstruktioner för varje programmeringsspråk för att fånga, logga och identifiera förväntade och ohanterade undantag i funktionskoden. Använd till exempel ett try/catch-block i C#, Java och JavaScript och dra nytta av försök och undantagsblock i Python för att hantera undantag.

  • Loggning: Genom att fånga ett undantag under körningen kan du logga viktig information som kan användas för att identifiera, återskapa och åtgärda problem på ett tillförlitligt sätt. Logga undantaget, inte bara meddelandet, utan även brödtexten, det inre undantaget och andra användbara artefakter som är användbara senare.

  • Fånga inte och ignorera undantag: En av de värsta sakerna du kan göra är att fånga ett undantag och inte göra något med det. Om du får ett allmänt undantag loggar du det någonstans. Om du inte loggar fel är det svårt att undersöka buggar och rapporterade problem.

Försök

Implementering av logik för återförsök i en arkitektur för händelseströmning kan vara komplext. Stöd för annulleringstoken, antal återförsök och exponentiella back off-strategier är bara några av de överväganden som gör det svårt. Som tur är tillhandahåller Functions återförsöksprinciper som kan kompensera för många av de här uppgifterna som du vanligtvis kodar själv.

Flera viktiga faktorer som måste beaktas när du använder återförsöksprinciperna med Event Hub-bindningen är:

  • Undvik obegränsade återförsök: När inställningen för maximalt antal återförsök har angetts till värdet -1 försöker funktionen på obestämd tid. I allmänhet bör obegränsade återförsök användas sparsamt med Functions och nästan aldrig med Event Hub-utlösarbindningen.

  • Välj lämplig strategi för återförsök: En strategi för fast fördröjning kan vara optimal för scenarier som får tillbaka trycket från andra Azure-tjänster. I dessa fall kan fördröjningen bidra till att undvika begränsningar och andra begränsningar som påträffas från dessa tjänster. Strategin för exponentiell säkerhetskopiering ger större flexibilitet för fördröjningsintervall för återförsök och används ofta vid integrering med tjänster från tredje part, REST-slutpunkter och andra Azure-tjänster.

  • Håll intervallen och återförsöken låga: Försök när det är möjligt att upprätthålla ett återförsöksintervall som är kortare än en minut. Behåll också det maximala antalet återförsök till ett någorlunda lågt antal. De här inställningarna är särskilt relevanta när de körs i funktionsförbrukningsplanen.

  • Kretsbrytarmönster: Ett tillfälligt fel från tid till tidpunkt förväntas och ett naturligt användningsfall för återförsök. Men om ett stort antal fel eller problem inträffar under bearbetningen av funktionen kan det vara klokt att stoppa funktionen, åtgärda problemen och starta om senare.

En viktig sak för återförsöksprinciperna i Functions är att det är en bra funktion för att bearbeta händelser. Det ersätter inte behovet av felhantering, loggning och andra viktiga mönster som ger återhämtning för din kod.

Strategier för fel och skadade data

Det finns flera anmärkningsvärda metoder som du kan använda för att kompensera för problem som uppstår på grund av fel eller felaktiga data i en händelseström. Några grundläggande strategier är:

  • Sluta skicka och läsa: Du kan åtgärda det underliggande problemet genom att pausa läsning och skrivning av händelser. Fördelen med den här metoden är att data inte går förlorade och att åtgärderna kan återupptas när en korrigering har distribuerats. Den här metoden kan kräva en kretsbrytarkomponent i arkitekturen och eventuellt ett meddelande till de berörda tjänsterna för att få en paus. I vissa fall kan det vara nödvändigt att stoppa en funktion tills problemen har lösts.

  • Ta bort meddelanden: Om meddelanden inte är viktiga eller anses vara icke-verksamhetskritiska kan du överväga att gå vidare och inte bearbeta dem. Den här metoden fungerar inte för scenarier som kräver stark konsekvens, till exempel att spela in rörelser i en schackmatch eller finansbaserade transaktioner. Felhantering i en funktion rekommenderas för att fånga och släppa meddelanden som inte kan bearbetas.

  • Försök igen: Det finns många situationer som kan motivera ombearbetning av en händelse. Det vanligaste scenariot är ett tillfälligt fel som uppstår när en annan tjänst eller ett annat beroende anropas. Nätverksfel, tjänstbegränsningar och tillgänglighet och stark konsekvens är kanske de vanligaste användningsfallen som motiverar ombearbetningsförsök.

  • Obeställbar bokstav: Tanken här är att publicera händelsen till en annan händelsehubb så att det befintliga flödet inte avbryts. Uppfattningen är att den flyttas från den heta vägen och kan hanteras senare eller av en annan process. Den här lösningen används ofta för hantering av förgiftade meddelanden eller händelser. Varje funktion som konfigureras med en annan konsumentgrupp stöter fortfarande på felaktiga eller skadade data i dataströmmen och måste hantera dem på ett ansvarsfullt sätt.

  • Försök igen och obeställbara bokstäver: Kombinationen av många återförsök innan du slutligen publicerar till en dataström med obeställbara bokstäver när ett tröskelvärde har uppnåtts är en annan välbekant metod.

  • Använd ett schemaregister: Ett schemaregister kan användas som ett proaktivt verktyg för att förbättra konsekvens och datakvalitet. Azure Schema Registry kan stödja övergången av scheman tillsammans med versionshantering och olika kompatibilitetslägen när scheman utvecklas. I grunden fungerar schemat som ett kontrakt mellan producenter och konsumenter, vilket kan minska risken för att ogiltiga eller skadade data publiceras till strömmen.

I slutändan finns det ingen perfekt lösning och konsekvenserna och kompromisserna med var och en av strategierna måste undersökas noggrant. Baserat på kraven kan det vara bäst att använda flera av dessa tekniker tillsammans.

Deltagare

Den här artikeln underhålls av Microsoft. Det har ursprungligen skrivits av följande medarbetare.

Huvudförfattare:

Om du vill se icke-offentliga LinkedIn-profiler loggar du in på LinkedIn.

Nästa steg

Innan du fortsätter bör du överväga att granska dessa relaterade artiklar:

Serverlös händelsebearbetning är en referensarkitektur som beskriver en typisk arkitektur av den här typen, med kodexempel och diskussion om viktiga överväganden.