Begränsningsmönster

Begränsa de resurser som en programinstans, en enskild klientorganisation eller en hel tjänst kan använda. På så sätt kan systemet fungera och uppfylla sina servicenivåmål (SLO) under plötslig eller ihållande belastning.

Kontext och problem

Belastningen på ett molnprogram varierar över tid baserat på aktiva användare och deras aktivitet. Fler användare loggar in under kontorstid och systemet kör beräkningsmässigt dyra analyser i slutet av varje månad. Plötsliga utbrott inträffar också. Om bearbetningsbehovet överskrider den tillgängliga kapaciteten saktar systemet ned eller misslyckas. Om systemet har en överenskommen servicenivå innebär det felet en överträdelse av servicenivåmålet.

Flera strategier hanterar varierande belastning, beroende på programmets affärsmål. En strategi är automatisk skalning, som matchar etablerade resurser med aktuell efterfrågan och styr kostnaden. Men etablering av nya resurser tar tid och lägger till kostnader. Efterfrågan som överskrider kapacitetstillväxten eller budgeten skapar ett resursunderskott.

Lösning

Ett alternativ till automatisk skalning är att begränsa resursanvändning och begränsa begäranden när användningen överskrider det taket. Arbetsbelastningen övervakar sin egen resursanvändning och begränsar begäranden från en eller flera användare när användningen överskrider tröskelvärdet. Systemet fortsätter att fungera och uppfylla sina SLO:er.

Strypning är en reglerslinga, inte ett enskilt beslut om att släppa igenom. Systemet behöver signaler med låg svarstid i tre lager: infrastrukturanvändning, programtillstånd och räknare per huvudnamn. Den mäter kontinuerligt mättnad, tillämpar gränser vid väldefinierade gränser och anpassar dessa gränser när trafikmönstren ändras. Överlagring är ett normalt driftsläge som ett moget system identifierar och återställer från. Begränsning ger självbevarande funktioner i din arbetsbelastning.

Systemet kan tillämpa flera strypnings- eller relaterade strategier:

  • Frekvensgränser per huvudnamn: Avvisa begäranden från en användare som redan har överskridit den konfigurerade hastigheten under ett definierat fönster. Denna strategi kräver att systemet kopplar varje begäran till en identitet och mäter resursanvändningen mot den identiteten. För arbetsbelastningar för flera klientorganisationer, se Mäta konsumtionen för varje klientorganisation.

  • Graciös funktionsförsämring: Inaktivera eller försämra icke-nödvändiga funktioner så att viktiga funktioner har tillräckligt med resurser. Den här strategin offrar fullständiga svar för högre tillgänglighet. Till exempel kan ett videoströmningsprogram sjunka till en lägre upplösning.

  • Belastningsutjämning: Jämna ut aktivitetsvolymen med hjälp av en kö. I en miljö med flera klienter minskar utjämning prestandan för varje klientorganisation. När hyresgäster har olika servicenivåavtal (SLA:er) ska du hantera arbete för hyresgäster med högt värde omedelbart och vänta med arbete med lägre prioritet tills arbetskön minskar. Implementera den här metoden med hjälp av mönstret Prioritetskö eller genom att exponera separata slutpunkter för varje prioritetsnivå.

  • Prioritetsbaserad uppskjutning: Skjut upp åtgärder för program eller klientorganisationer med lägre prioritet. Avbryt eller begränsa operationer och returnera ett undantag som anger att klientorganisationen ska försöka igen senare.

  • Utgående hastighetsgränser: Begränsa dina egna utgående anrop när ett externt beroende misslyckas eller returnerar fel. Minska antalet förfrågningar under flygning för att stoppa översvämningsloggar och för att undvika återförsökskostnader mot ett felfritt beroende. Återställ det normala begärandeflödet när beroendet har återställts. Till exempel implementerar NServiceBus den här funktionen.

Följande diagram visar resursanvändning (en kombination av minne, PROCESSOR, bandbredd och andra faktorer) över tid för ett program som använder tre funktioner, märktA, B och C. En funktion är ett specifikt funktionsområde, till exempel en komponent som utför en specifik uppsättning uppgifter, en kod som utför en komplex beräkning eller ett element som tillhandahåller en tjänst, till exempel en minnesintern cache.

Diagram som visar resursanvändning mot tid för program som körs för tre användares räkning.

Ett linjediagram ritar resursanvändningen på y-axeln mot tiden på x-axeln. Tre färgade linjer representerar funktion A, funktion B och funktion C, med funktion A:s linje lägst, funktion B:s linje i mitten och funktion C:s linje högst. En solid vågrät linje nära toppen av diagrammet markerar maximal kapacitet, och en streckad vågrät linje under den markerar den mjuka gränsen för resursutnyttjande. Två lodräta streckade linjer markerar gångerna T1 och T2. Före T1 fluktuerar alla tre funktionslinjerna och Funktion C:s linje stiger och korsar den mjuka gränsen. Vid T1 sjunker funktion B:s kurva till noll och ligger kvar på noll till T2 eftersom funktion B pausas för att frigöra resurser för funktion A och funktion C. Funktion C:s kurva sjunker tillbaka under den mjuka gränsen mellan T1 och T2, medan funktion A fortsätter normalt. Vid T2 återupptas funktion B och alla tre linjerna fortsätter att fluktuera under den mjuka gränsen.

Diagrammet är ett staplat ytdiagram. Området under funktion A:s rad visar de resurser som funktion A förbrukar, området mellan raderna funktion A och funktion B visar de resurser som funktion B förbrukar och området mellan raderna funktion B och funktion C visar de resurser som funktion C förbrukar. Funktion C:s linje ligger överst i stacken, så den visar även total användning av systemresurser över tid.

Diagrammet visar en gradvis försämring av funktionaliteten. Strax före tid T1 närmar sig den totala resursanvändningen tröskelvärdet och riskerar att uttömma tillgänglig kapacitet. Funktion B är mindre kritisk än funktion A eller funktion C, så systemet stänger av funktion B och släpper sina resurser. Mellan gångerna T1 och T2 fortsätter funktion A och funktion C normalt. Efter tid T2 minskar den totala resursanvändningen tillräckligt för att aktivera funktion B igen.

Du kan kombinera autoskalning, kontrollerad degradering och strypning för att hålla applikationer responsiva och inom SLA:er. När du förväntar dig att efterfrågan ska förbli hög upprätthåller strypning stabiliteten medan systemet skalas ut. När skalningen har slutförts återställer systemet full funktionalitet.

Nästa diagram visar den totala resursanvändningen över tid och hur strypning samverkar med automatisk skalning och andra kompenserande styrmekanismer.

Graf som visar effekterna av att kombinera strypning med autoskalning.

Ett linjediagram ritar resursanvändning för alla program på y-axeln mot tiden på x-axeln. Två vågräta referenslinjer markerar den mjuka gränsen för resursanvändning och den maximala kapaciteten före autoskalning. En högre vågrät linje, som börjar vid tidpunkten T2, markerar den maximala kapaciteten efter autoskalning. Användningslinjen ökar och varierar över tid. Den passerar den mjuka gränsen vid tidpunkten T1, det vill säga den punkt då autoskalning börjar. Mellan T1 och T2 stryps systemet medan autoskalning sker, och resursutnyttjandet ligger under den maximala kapaciteten före autoskalning. Vid tidpunkt T2 slutförs autoskalningen, begränsningen lättas och utnyttjandekurvan hoppar upp och fortsätter att variera under den nya, högre maxkapaciteten.

Vid tidpunkten för T1 når systemet den mjuka gränsen och börjar skala ut. Om nya resurser inte tas emot i tid kan efterfrågan uttömma befintliga resurser och systemet kan misslyckas. Strypning avvisar för många begäranden vid uppskalning för att hålla resursanvändningen under den hårda gränsen och häver sedan dessa begränsningar när ny kapacitet blir tillgänglig.

Tip

Gränskontroller och begränsningsmönstret åtgärdar olika problem. Perimeterskydd, till exempel Azure DDoS Protection och hastighetsbegränsningsregler för brandvägg för webbprogram (WAF), tillämpas vid nätverksgränsen och stoppar volymbaserad eller skadlig trafik innan den når din applikation. Strypningsmönstret körs i ditt program och avpassar legitim trafik mot programdefinierade gränsvärden. Använd båda lagren tillsammans. DDoS-skydd hindrar inte en legitim användare från att överbelasta tjänsten, och programbegränsningen absorberar inte en volymriskattack.

Problem och överväganden

Tänk på följande när du bestämmer hur du ska implementera det här mönstret:

  • Fatta beslut om begränsning tidigt. Strypning är ett arkitekturbeslut som påverkar hela systemet. Att eftermontera det senare är dyrt.

  • Anpassa begränsningsgränserna efter den komponent som först blir fullt utnyttjad.

    Begärandefrekvensen är den mest välbekanta dimensionen att begränsa, men den verkliga flaskhalsen är ofta samtidiga förfrågningar under flygning, ködjup, PROCESSOR- eller minnesanvändning eller ett underordnat beroendes egna gränser. En gräns för förfrågningar per sekund skyddar inte ett system vars flaskhals är samtidiga förfrågningar vid en förgreningspunkt.

    Vid varje gräns där begränsning tillämpas, till exempel gatewayen, tjänsten, en partition eller ett nedströmsberoende, identifiera vilken resurs som först blir mättad och sätt gränsen för den dimensionen. För skydd med begränsad samtidighet vid fan-out-punkter, se Bulkhead-mönstret, som kompletterar begränsning av genomströmning.

  • Välj en begränsande algoritm avsiktligt. Matcha den med toleransen för den komponent som du skyddar.

    Algorithm Beteende och bästa passform
    Token-bucket Stöder bursts upp till en konfigurerad storlek och framtvingar en stadig påfyllningshastighet. Används för gatewayer som behöver absorbera korta toppar.
    Läckande bucket Avger med konstant hastighet. Använd för backend-system som behöver en jämn inkommande trafik.
    Fast fönster Enkelt att implementera, men medger burstar i direkt följd vid fönstergränser.
    Skjutfönster Jämnar ut fönstergränsproblemet för fasta fönster på bekostnad av mer tillståndsinformation.
  • Bestäm vem gränsen påverkar. Begränsning av trafik på en övergripande nivå, till exempel i en regional gateway, kan påverka många oberoende användare när det bara är ett fåtal av dem som orsakar belastningen.

  • Bestäm var räknaren finns när en gräns sträcker sig över flera noder. Lokala räknare är snabba men underskattar antalet när samma klient når flera repliker. En centraliserad räknare i ett delat arkiv som Redis ser varje begäran men lägger till svarstid för varje beslut. Om du vill approximera en global hastighet delar du upp gränsen över replikerna och stämmer av med jämna mellanrum.

  • Fatta beslut om begränsning snabbt. Systemet måste identifiera ökande belastning, reagera och återgå till det normala när belastningen har minskat. Den här processen kräver kontinuerlig prestandainstrumentation.

  • Kasta belastning proaktivt, inte vid kanten av kollapsen. En strypning som börjar avvisa först efter att en komponent har nått kapacitetstaket får svarstiden att skjuta i höjden innan anropande klienter märker något baktryck.

    När användningen närmar sig den hårda gränsen börjar du avvisa en växande del av begäranden. Tidiga avvisningssignaler får anropare att backa och förhindrar den latenskollaps som tvära begränsningar ofta utlöser. Använd p99-svarstid mot ditt SLO som primär utlösare. Det genomsnittliga resursutnyttjandet kan se bra ut samtidigt som p99 redan har överskridit gränsvärdet.

    Där du kan skilja mellan förfrågningars värde bör du först välja bort arbete med lägre värde eller arbete som lättare kan köras om. Mer information finns i mönstret Prioritetskö.

  • Returnera en statuskod som anger för klienten när en tillfällig avvisning beror på begränsning av begärandefrekvensen:

    • HTTP 429 (för många begäranden): Anroparen överskrider en konfigurerad begärandefrekvens över ett definierat fönster.
    • HTTP 503 (tjänsten är inte tillgänglig): Tjänsten kan inte hantera begäran just nu, ofta på grund av en oväntad belastningstoppar.

    Inkludera ett Retry-After HTTP-huvud så att klienten kan välja en återförsöksstrategi. Returnera tillräckligt med kontext för att anroparen ska kunna försöka igen avsiktligt i stället för att gissa. Namnge till exempel den gräns som anroparen överskrider, klargöra det berörda omfånget eller föreslå en hastighet som skulle lyckas. Oförklarliga avslag hjälper inte uppringare att anpassa sig.

  • Vidarebefordra överbelastningssignaler från dina beroenden i stället för att absorbera dem. En tjänst som begränsar anropshastigheten för sina anropare måste också respektera de begränsningssvar som den får från sina egna nedströmsberoenden. Om tjänsten döljer ett 429- eller 503-svar från en underliggande tjänst genom att göra tysta omförsök eller genom att returnera ett generiskt HTTP 500-svar (Internal Server Error), kan anropare inte sänka takten, omförsöken ökar och överbelastningen fortplantar sig tillbaka uppströms. Antimönstret Retry Storm beskriver det här felläget. Förmedla bakåttryck till anropare uppströms så att hela anropskedjan minskar belastningen tillsammans.

  • Gör avslag billigare än det arbete som det förhindrar. Om nekande av en begäran kräver omfattande autentisering, djup parsning eller komplex principutvärdering kan en flod av avvisade begäranden fortfarande mätta systemet. Avvisa så tidigt som möjligt i begärandekedjan och belastningstesta själva avvisningsflödet.

  • Planera för situationer där strypning inte kan ge tillräckligt med tid för automatisk skalning. Om efterfrågan växer snabbare än ny kapacitet tas i drift kan även ett strypt system fallera. När det resultatet är oacceptabelt behåller du större kapacitetsreserver och konfigurerar mer aggressiv autoskalning.

  • Använd inte cachelagring i stället för strypning. En cache sänker den genomsnittliga belastningen på ursprunget men begränsar inte den högsta belastningen. Varje cachemiss går vidare till ursprungsservern, och när en populär nyckel löper ut vid hög belastning kan många anrop försöka fylla den igen. Använd cachelagring för att minska den normala belastningen och strypning för att begränsa utfallet i värsta fall. Mer information finns i mönstretCache-Aside.

  • Normalisera resurskostnader för olika åtgärder eftersom de vanligtvis inte medför samma körningskostnader. Strypningsgränser kan till exempel vara högre för läsåtgärder och lägre för skrivåtgärder. Om du ignorerar kostnaden per åtgärd kan kapaciteten förbrukas och en attackvektor skapas.

  • Gör att strypningskonfigurationen kan ändras vid körning. När onormal last uppstår behöver du justera gränsvärden utan driftsättning. Distributionerna är långsamma och riskfyllda under en incident. Mönstret Extern konfigurationslagring externaliserar konfigurationen så att du kan ändra den vid körning.

  • Överväg anpassningsbara gränser i stället för statiska gränser. Vissa begränsnings-SDK:er reagerar på svarstider eller ködjupsignaler så att gränsen spårar faktiska komponentförhållanden. Kombinera alltid en adaptiv limiter med ett fastställt maxvärde.

  • Gå tillbaka till dina gränser när arbetsbelastningen utvecklas. Anpassningsbara begränsare kan inte spåra alla typer av drift, till exempel SLO-ändringar, ändringar i beroendekapacitet eller förändringar i kostnaden per åtgärd. Schemalägg periodisk operatörsgranskning mot dessa indata.

När du ska använda det här mönstret

Använd det här mönstret:

  • För att hålla ett system inom sina SLO:er.

  • För att förhindra att en enskild klientorganisation monopoliserar programresurser.

  • För att hantera ökningar av aktivitet.

  • Begränsa den maximala resursnivå som ett system behöver.

  • För att minska lågvärdesberäkning under perioder med hög kolintensitet i rutnätet.

Design av arbetsbelastning

Utvärdera hur du kan använda strypningsmönstret i utformningen av en arbetsbelastning för att uppfylla de mål och principer som behandlas i grundpelarna i Azure Well-Architected Framework. Följande tabell innehåller vägledning om hur det här mönstret stöder målen för varje pelare.

Grundpelare Så här stöder det här mönstret pelarmål
Tillförlitlighets designbeslut hjälper din arbetsbelastning att bli motståndskraftig mot funktionsfel och säkerställer att den återställer sig till ett fullständigt fungerande tillstånd när ett fel uppstår. Du utformar gränserna för att förhindra resursöverbelastning som kan leda till fel. Du kan också använda det här mönstret som en kontrollmekanism i en kontrollerad nedbrytningsplan.

- RE:07 Självbevarande
Beslut om säkerhetsdesign bidrar till att säkerställa konfidentialitet, integritet och tillgänglighet för arbetsbelastningens data och system. Du kan utforma gränserna för att förhindra resursöverbelastning som kan uppstå till följd av automatiserat missbruk av systemet.

- SE:06 Nätverkskontroller
- SE:08 Härdningsresurser
Kostnadsoptimering fokuserar på att upprätthålla och förbättra arbetsbelastningens avkastning på investeringen. De framtvingade gränserna kan ligga till grund för kostnadsmodellering och kan vara direkt kopplade till programmets affärsmodell. De lägger också tydliga övre gränser på användningen, som kan räknas in i resursstorleken.

- CO:02 Kostnadsmodell
- Skalkostnader för CO:12
Prestandaeffektivitet hjälper din arbetsbelastning effektivt uppfylla kraven genom optimering av skalning, data och kod. När systemet är under hög efterfrågan hjälper det här mönstret till att minska överbelastningen som kan leda till flaskhalsar i prestanda. Du kan också använda den för att proaktivt undvika scenarier med bullriga grannar.

- PE:02 Kapacitetsplanering
- PE:05 Skalning och partitionering

Om detta mönster inför kompromisser inom en pelare bör du överväga dem mot målen för de andra pelarna.

Example

I följande diagram visas begränsningar i ett system med flera klientorganisationer.

Diagram som visar strypning i en flerklientapplikation.

Tre namngivna användare till vänster representerar hyresgäster i multitenant-programmet Surveys: Adatum, Fabrikam och Contoso. Varje användare skickar begäranden via en klientspecifik anpassad domän, som programmet använder för att identifiera klientorganisationen. Adatum skickar 5 begäranden per sekund via surveys.adatum.com, Fabrikam skickar 10 begäranden per sekund via surveys.fabrikam.com och Contoso skickar 150 begäranden per sekund via surveys.contoso.com. Till höger mäter webbrollen för enkätapplikationen antalet begäranden per sekund för varje klientorganisation. Adatum- och Fabrikam-begärandeflödena skickas till programmet. Contoso-begärandeflödet blockeras av felet: begränsat svar eftersom begärandefrekvensen överskrider gränsvärdet per klientorganisation.

Användare från flera klientorganisationer får åtkomst till ett molnbaserat program för att fylla i och skicka undersökningar. Programmet innehåller instrumentation som övervakar den hastighet med vilken varje klientorganisations användare skickar begäranden.

För att förhindra att användare från en klientorganisation försämrar svarstiden och tillgängligheten för användare i andra klientorganisationer begränsar programmet den frekvens för begäranden per sekund som en enskild klientorganisation kan skicka. Programmet blockerar förfrågningar som överskrider den här gränsen.

Nästa steg