Enhet 8 / 11

Hastighetsgränser och resilient felhantering

Vinster:

  • Kan tolka hastighetsgränser (RPM/ITPM/OTPM) och 429 fel
  • Implementerar exponentiell backoff och försök igen med försök igen
  • Klassificerar och hanterar vanliga HTTP-felkoder korrekt (400/401/429/500/529)

I en produktionsmiljö svarar inget API perfekt hela tiden. Ibland skickar du förfrågningar för snabbt och når gränsen; ibland är servern tillfälligt upptagen; Ibland är din begäran felaktig från början. Det som skiljer en solid integration från ett amatörförsök är att den hanterar dessa situationer prediktivt och automatiskt. I den här enheten kommer du att lära dig om hastighetsgränser (RPM/ITPM/OTPM), 429-fel, försök igen med exponentiell backoff och korrekt klassificering av vanliga HTTP-felkoder. Målet: att bygga ett flöde som är så robust att en användare aldrig kommer att märka det.

Vad är hastighetsgränser?

Leverantören begränsar hur mycket arbete en switch kan göra under en given tidsperiod. Detta skydd; Det skyddar både infrastrukturen och dig från plötsliga kostnadsexplosioner. Det finns tre vanliga typer av gränser:

  • RPM (Requests Per Minute): Antal förfrågningar per minut.
  • ITPM (Input Tokens Per Minute): Indatatoken som kan bearbetas per minut.
  • OTPM (Output Tokens Per Minute): Utdatatoken som kan produceras per minut.

Om du överskrider någon av dessa gränser, avvisar leverantören begäran och returnerar en 429-felkod. Gränserna varierar i allmänhet beroende på din kontonivå (nivå) och kan ökas med tiden.

Tips: Du kan se när du närmar dig gränsen från svarsrubriker. De flesta leverantörer rapporterar din återstående kvot med rubriker som x-ratelimit-remaining-*. Att övervaka dessa värden och strypa trafiken framför är det mest mogna sättet att förhindra problemet utan att få en 429.

429 och exponentiell retracement

429 (hastighetsgräns) är ett tillfälligt fel som går att försöka igen. Det korrekta svaret är att vänta på begäran ett tag och försöka igen. Men en konstant väntan räcker inte; Om alla försöker igen samtidigt nås gränsen igen. Lösningen är exponentiell backoff: att öka väntetiden exponentiellt för varje misslyckat försök.

# Exponentiell backoff-logikförsök 1 → 429 → vänta 1 sek försök 2 → 429 → vänta 2 sek försök 3 → 429 → vänta 4 sek försök 4 → 429 → vänta 8 sek (+ litet slumpmässigt "jitter")... ge upp och rapportera efter högst N försök

Att lägga till lite slumpmässighet (jitter) till detta förhindrar att förfrågningar kolliderar när man försöker igen samtidigt. Dessutom har 429-svaret ofta en "försök igen efter"-huvudet: "försök igen om så många sekunder". Att respektera denna titel är mer korrekt än att blint vänta.

Varning: När du får en 429:a, "tvinga den genom att skicka fler förfrågningar" kommer att göra situationen värre; Gränsen fortsätter att fyllas och inga förfrågningar går igenom. Det korrekta svaret är reträtt, inte acceleration. Goda nyheter: de flesta officiella SDK:er försöker automatiskt igen 429 och serverfel med en backoff — använd detta beteende hos SDK:n innan du installerar det manuellt.

Klassificering av HTTP-felkoder

Alla misstag är inte desamma. Kritisk skillnad: kan det prövas igen eller är det en begäran/identitetsfråga?

Kod

Mening

Går det att prova igen?

korrekt svar

400

Ogiltig begäran (format-/parameterfel)

nej

Rätta begäran; skicka inte samma igen

401

Autentiseringsfel (nyckel ogiltig/saknas)

nej

Fixa nyckel/titel

403

Ingen auktorisering (ingen tillgång till modell/funktion)

nej

Kontrollera behörigheter/omfattning

404

Hittade inte (felaktig modell-ID/slutpunkt)

nej

Rätt modell-ID/adress

429

Hastighetsgränsen har överskridits

Ja

Retreat + återförsök-efter

500

Serverfel

Ja

Försök igen med reträtt

529

Server överbelastad

Ja

Försök igen med reträtt

Gyllene regeln: 429, 500 och 529 är tillfälliga; Det prövas igen med tillbakadragande. 400, 401, 403, 404 är frågor om begäran/identitet; Att försöka igen kommer inte att lösa det, och det är slöseri med ansträngning. Din kod måste skilja mellan dessa två grupper.

Steg för steg: Varaktigt samtal

  1. Skicka in begäran. Om det lyckas, fortsätt.
  2. Klassificera felkoden. Går det att prova igen?
  3. Om det går att prova: följ ett nytt försök efter, tillämpa exponentiell backoff + jitter, försök ett begränsat antal gånger (t.ex. max 5).
  4. Om inte försökt: Fixa (format/nyckel) och stoppa; Upprepa inte samma felaktiga begäran i slingan.
  5. Överväg att ge upp. Om fortfarande misslyckas efter n försök, visa ett artigt meddelande till användaren och logga händelsen (spårningsenhet 11).

# Robust call pseudo-codedene = 0repeat: response = request_at() if response.success: returnera svar if response.code i [429, 500, 529] och försök < 5: wait = retry_after ?? (2^försök sek + jitter) sömn(vänta); försök += 1; git igen om respons.kod i [400, 401, 403, 404]: save_error(response); returnera "begäran måste åtgärdas" returnera "permanent fel, försök senare"

# Artig feedback till användaren (när försöken är slut) "Jag är upptagen just nu, jag kunde inte behandla din förfrågan. Försök igen snart, annars har jag sparat din förfrågan, jag återkommer till dig när den är klar."

Svag prompt / Stark prompt (här: felmeddelandedesign)

# SVAG (visar råfel för användaren)"Fel 429: rate_limit_error"

# STARK (användarvänlig, lugnande, åtgärdsföreslår) "Det var en tillfällig överbelastning i systemet. Vi har tagit emot din förfrågan på ett säkert sätt och den prövas igen automatiskt. Om ett resultat inte visas inom några sekunder kan du uppdatera sidan."

Att avslöja det råa tekniska felet för slutanvändaren både undergräver förtroendet och kan vara en säkerhetsrisk. Kategorisera fel internt och ge användaren ett lugnt, handlingsorienterat meddelande; skriv bara den tekniska detaljen för protokollet.

Tre minifodral

Fall 1 – Båt kraschade i trafikexplosion. En kundtjänstbot fick 429 i ökningstrafik på kampanjdagen; Det fanns inget nytt försök i koden, varje fel återspeglades direkt till användaren som ett "fel". De lade till exponentiell retracement + retry-efter; med samma trafik, förfrågningar passerade med en fördröjning på flera sekunder, såg användaren inga fel.

Fall 2 — Försöker 400 i slingan. En integration fick en 404 på grund av ett ogiltigt modell-ID, men behandlade alla fel som "övergående" och försökte igen i en oändlig loop; Stocken blev svullen och onödig belastning skapades. De lade till felklassificering: 404 anses vara permanent, slingan stoppas och modell-ID korrigeras. Lektion: försök inte varje misstag igen.

Fall 3 — Hantera gränsen framifrån. Ett databerikande jobb kördes konstant vid gränsen 429. De följde x-ratelimit-resterande rubrik och strypte trafiken enligt kvoten. Så de höll ett jämnt tempo strax under gränsen, utan att ta några 429:or; Jobbet gjordes mer förutsägbart och snabbare.

Vanliga misstag

  • Ökar hastigheten i 429: Förvärrar situationen; Byt till reträtt.
  • Försöker igen varje fel: 400/401/404 är permanent; Att försöka igen är ett slöseri.
  • Använda fast väntan: Skapar en kollision; Använd exponentiell + jitter.
  • Att ignorera "försök igen efter": Det är mest korrekt att följa den tid som anges av leverantören.
  • Att avslöja det råa felet för användaren: Skakar förtroendet, skapar sårbarheter; Klassificera inuti.
  • Obegränsade försök: Ställ in en övre gräns (t.ex. 5 försök); ge sedan upp graciöst.

Djupare: Kö, samtidighet och effektbrytare

En enda önskans uthållighet är det första steget; Den verkliga mognaden är att hantera ett stort antal förfrågningar utan att nå gränserna. Tre begrepp spelar in här.

Kö: Du lägger förfrågningar i en kö för att skicka dem i en kontrollerad takt snarare än omedelbart. Kö slätar ut plötsliga skurar av trafik: Även om 1 000 förfrågningar kommer på en gång kommer kön att släppa dem i en takt under gränsen. På så sätt förhindrar du 429, då behöver du inte oroa dig för att fixa det.

Samtidighetsgräns: Du begränsar hur många förfrågningar som är "i luften" samtidigt. Obegränsade parallella förfrågningar fyller snabbt RPM- och TPM-gränserna. Ett rimligt samtidighetstak (t.ex. inte mer än 10 samtidiga förfrågningar) både upprätthåller gränser och gör systemet förutsägbart.

Strömbrytare: Om leverantören fortsätter att returnera 500/529, istället för att envist försöka varje begäran, "bryter du kretsen" ett tag och misslyckas snabbt förfrågan utan att någonsin skicka den. Efter en väntan slår du på kretsen igen och försöker. Det här mönstret förhindrar ditt system från att krascha i händelse av ett tillfälligt leverantörsfel.

Tillsammans etablerar dessa tre motståndskraft på systemnivå bortom logiken för att försöka igen för ett enda samtal. I liten skala är SDK:s automatiska återförsök tillräckligt; När skalan växer blir köer, samtidighet och strömbrytare oumbärliga. De har alla samma gemensamma mål: att återspegla ett tillfälligt problem för användaren inte som en krasch, utan som en osynlig fördröjning på några sekunder.

Sammanfattningsvis

429 återgår när hastighetsgränserna (RPM/ITPM/OTPM) överskrids; Detta är ett tillfälligt fel och kommer att försökas igen med hjälp av försök efter och exponentiell backoff + jitter. 500 och 529 är också provisoriska; 400/401/403/404 är ett förfrågan/identitetsproblem och kan inte lösas genom att försöka igen. Ett robust flöde separerar fel i dessa två grupper, försöker ett begränsat antal gånger, övervakar gränsen framifrån och visar lugna meddelanden till användaren.

Applikationsuppgift

Tänk på din integration. (1) Lista de felkoder du kan stöta på och separera dem i "omförsökbara / permanenta". (2) Skriv ner din exponentiella tillbakadragningsplan (initial hold, koefficient, cap, jitter). (3) Ange hur du använder rubriken för att försöka igen efter. (4) Skriv det artiga meddelandet som ska visas för användaren när nya försök är slut.

checklista

  • [ ] Jag kan förklara RPM/ITPM/OTPM-gränser och 429.
  • [ ] Jag kan tillämpa logiken för exponentiell reträtt + jitter + försök efter.
  • [ ] Jag kan klassificera felkoder som omförsökbara/permanenta.
  • [ ] Jag vet att vi inte bör pröva alla misstag.
  • [ ] Istället för ett råfel kan jag visa användaren ett lugnt, handlingsinriktat meddelande.