Enhed 8 / 11

Hastighedsgrænser og modstandsdygtig fejlstyring

Gevinster:

  • Kan fortolke hastighedsgrænser (RPM/ITPM/OTPM) og 429 fejl
  • Implementerer eksponentiel backoff og genforsøg med genforsøg efter
  • Klassificerer og håndterer almindelige HTTP-fejlkoder korrekt (400/401/429/500/529)

I et produktionsmiljø reagerer ingen API perfekt hele tiden. Nogle gange sender du forespørgsler for hurtigt og rammer grænsen; nogle gange er serveren midlertidigt optaget; Nogle gange er din anmodning forkert fra begyndelsen. Det, der adskiller en solid integration fra et amatørforsøg, er, at den håndterer disse situationer forudsigeligt og automatisk. I denne enhed lærer du om hastighedsgrænser (RPM/ITPM/OTPM), 429-fejl, forsøg igen med eksponentiel backoff og korrekt klassificering af almindelige HTTP-fejlkoder. Målet: at opbygge et flow, der er så robust, at en bruger aldrig vil bemærke det.

Hvad er hastighedsgrænser?

Udbyderen begrænser, hvor meget arbejde et skifte kan udføre i en given periode. Denne beskyttelse; Det beskytter både infrastrukturen og dig mod pludselige omkostningseksplosioner. Der er tre almindelige typer grænser:

  • RPM (Requests Per Minute): Antal anmodninger pr. minut.
  • ITPM (Input Tokens Per Minute): Input-token, der kan behandles per minut.
  • OTPM (Output Tokens Per Minute): Output-token, der kan produceres per minut.

Hvis du overskrider nogen af ​​disse grænser, afviser udbyderen anmodningen og returnerer en 429 fejlkode. Grænserne varierer generelt afhængigt af dit kontoniveau (tier) og kan øges over tid.

Tip: Du kan se, når du nærmer dig grænsen, fra svaroverskrifterne. De fleste udbydere rapporterer din resterende kvote med overskrifter som x-ratelimit-remaining-*. Overvågning af disse værdier og drosling af trafikken foran er den mest modne måde at forhindre problemet på uden at få en 429.

429 og eksponentiel retracement

429 (satsgrænse) er en midlertidig fejl, der kan prøves igen. Det korrekte svar er at vente på anmodningen et stykke tid og prøve igen. Men en konstant venten er ikke nok; Hvis alle prøver igen på samme tid, nås grænsen igen. Løsningen er eksponentiel backoff: at øge ventetiden eksponentielt for hvert mislykket forsøg.

# Eksponentiel backoff logik forsøg 1 → 429 → vent 1 sek prøve 2 → 429 → vent 2 sek prøve 3 → 429 → vent 4 sek prøve 4 → 429 → vent 8 sek (+ lille tilfældig "jitter")... giv op og rapporter efter højst N forsøg

Tilføjelse af lidt tilfældighed (jitter) til dette forhindrer anmodninger, der kolliderer, når du prøver at prøve igen på samme tid. Derudover har 429-svaret ofte en "gentag-efter"-header: "try again in this many seconds". At respektere denne titel er mere præcis end at vente blindt.

Forsigtig: Når du får en 429, vil "tvinge den ved at sende flere anmodninger" gøre situationen værre; Grænsen fortsætter med at blive udfyldt, og ingen anmodninger går igennem. Det korrekte svar er tilbagetrækning, ikke acceleration. Gode ​​nyheder: de fleste officielle SDK'er prøver automatisk 429 og serverfejl med en backoff - brug denne adfærd fra SDK'et, før du installerer det manuelt.

Klassificering af HTTP-fejlkoder

Ikke alle fejl er de samme. Kritisk skelnen: kan det prøves igen, eller er det et spørgsmål om anmodning/identitet?

Kode

Betydning

Kan det prøves igen?

korrekte svar

400

Ugyldig anmodning (format-/parameterfejl)

nej

Ret anmodningen; send ikke det samme igen

401

Godkendelsesfejl (nøgle ugyldig/mangler)

nej

Ret nøgle/titel

403

Ingen autorisation (ingen adgang til model/funktion)

nej

Tjek tilladelser/omfang

404

Ikke fundet (forkert model-id/slutpunkt)

nej

Korrekt model ID/adresse

429

Hastighedsgrænsen overskredet

Ja

Retreat + genforsøg-efter

500

Serverfejl

Ja

Prøv igen med tilbagetrækning

529

Server overbelastet

Ja

Prøv igen med tilbagetrækning

Gylden regel: 429, 500 og 529 er midlertidige; Det prøves igen med tilbagetrækning. 400, 401, 403, 404 er anmodninger/identitetsproblemer; At prøve igen løser det ikke, og det spilder kræfter. Din kode skal skelne mellem disse to grupper.

Trin for trin: Holdbart opkald

  1. Indsend anmodningen. Hvis det lykkes, fortsæt.
  2. Klassificer fejlkoden. Kan det prøves igen?
  3. Hvis det kan prøves: følg genforsøg efter, anvend eksponentiel backoff + jitter, prøv et begrænset antal gange (f.eks. maks. 5).
  4. Hvis ikke prøvet: Fix (format/tast) og stop; Gentag ikke den samme fejlagtige anmodning i løkken.
  5. Overvej at give op. Hvis det stadig ikke lykkes efter n forsøg, vis en høflig besked til brugeren og log hændelsen (sporingsenhed 11).

# Robust kald pseudo-codedene = 0repeat: respons = request_at() if response.success: returner respons if response.code i [429, 500, 529] og prøv < 5: wait = retry_after ?? (2^try sec + jitter) sleep(vent); prøv += 1; git igen hvis respons.kode i [400, 401, 403, 404]: save_error(response); returner "anmodning skal rettes" return "permanent fejl, prøv senere"

# Høflig feedback til brugeren (når genforsøg er opbrugt) "Jeg har travlt lige nu, jeg kunne ikke behandle din anmodning. Prøv igen snart, eller jeg har gemt din anmodning, jeg vender tilbage til dig, når den er klar."

Svag prompt / stærk prompt (her: fejlmeddelelsesdesign)

# SWAG (viser rå fejl til bruger)"Fejl 429: rate_limit_error"

# STÆRK (brugervenlig, beroligende, handlings-antydende) "Der var en midlertidig overbelastning i systemet. Vi har modtaget din anmodning sikkert, og den forsøges automatisk igen. Hvis et resultat ikke vises inden for få sekunder, kan du opdatere siden."

At afsløre den rå tekniske fejl for slutbrugeren både underminerer tilliden og kan være en sikkerhedssårbarhed. Kategoriser fejl internt og giv brugeren en rolig, handlingsorienteret besked; bare skriv den tekniske detalje for ordens skyld.

Tre mini etuier

Tilfælde 1 - Båden styrtede ned i trafikeksplosion. En kundeservicebot modtog 429 i stigningstrafik på kampagnedagen; Der var ingen genforsøg i koden, hver fejl blev afspejlet direkte til brugeren som en "fejl". De tilføjede eksponentiel retracement + retry-efter; med den samme trafik, forespørgsler bestået med en forsinkelse på flere sekunder, så brugeren ingen fejl.

Case 2 — Prøver 400 i løkken. En integration fik en 404 på grund af et ugyldigt model-id, men behandlede alle fejl som "forbigående" og prøvede igen i en uendelig løkke; Kævlen blev hævet, og unødvendig belastning blev skabt. De tilføjede fejlklassificering: 404 betragtes som permanent, løkken stoppes, og model-ID'et er rettet. Lektion: prøv ikke hver fejl igen.

Case 3 — Håndtering af grænsen forfra. Et databerigelsesjob kørte konstant ved grænsen på 429. De fulgte x-ratelimit-resterende header og droslede trafikken i henhold til kvoten. Så de holdt et stabilt tempo lige under grænsen, uden at tage nogen 429'ere; Jobbet blev udført mere forudsigeligt og hurtigere.

Almindelige fejl

  • Stigende hastighed i 429: Gør situationen værre; Skift til tilbagetog.
  • Prøver hver fejl igen: 400/401/404 er permanent; At prøve igen er spild.
  • Brug af fast ventetid: Skaber en kollision; Brug eksponentiel + jitter.
  • Ignorerer 'genforsøg efter': Det er mest nøjagtigt at overholde den tid, der er angivet af udbyderen.
  • Afsløring af den rå fejl for brugeren: Ryster tilliden, skaber sårbarheder; Klassificer indeni.
  • Ubegrænsede forsøg: Indstil en øvre grænse (f.eks. 5 forsøg); giv så yndefuldt op.

Dybere: Kø-, samtidigheds- og strømafbrydere

Udholdenheden af et enkelt ønske er det første skridt; Den virkelige modenhed er at håndtere et stort antal anmodninger uden at ramme grænserne. Tre begreber spiller ind her.

Kø: Du sætter anmodninger i en kø for at sende dem i et kontrolleret tempo snarere end med det samme. Kø udjævner pludselige udbrud af trafik: Selv hvis der kommer 1.000 anmodninger på én gang, vil køen frigive dem med en hastighed under grænsen. På denne måde forhindrer du 429, så behøver du ikke bekymre dig om at ordne det.

Samtidig grænse: Du begrænser, hvor mange anmodninger, der er "i luften" på samme tid. Ubegrænsede parallelle anmodninger udfylder hurtigt RPM- og TPM-grænser. Et rimeligt samtidighedsloft (fx ikke mere end 10 samtidige anmodninger) både opretholder grænser og gør systemet forudsigeligt.

Circuit breaker: Hvis udbyderen bliver ved med at returnere 500/529, i stedet for ihærdigt at prøve hver anmodning, "bryder du kredsløbet" i et stykke tid og fejler hurtigt anmodningen uden nogensinde at sende den. Efter en ventetid tænder du for kredsløbet igen og prøver. Dette mønster forhindrer dit system i at gå ned i tilfælde af en midlertidig udbyderfejl.

Tilsammen etablerer disse tre modstandsdygtighed på systemniveau ud over genforsøgslogikken for et enkelt opkald. I lille skala er SDK'ens automatiske genforsøg tilstrækkeligt; Efterhånden som skalaen vokser, bliver kø, samtidighed og strømafbryder uundværlige. De har alle det samme fælles mål: at afspejle et midlertidigt problem for brugeren, ikke som et nedbrud, men som en usynlig forsinkelse på et par sekunder.

Sammenfattende

429 vender tilbage, når hastighedsgrænserne (RPM/ITPM/OTPM) overskrides; Dette er en midlertidig fejl og vil blive forsøgt igen ved at bruge genforsøg efter og eksponentiel backoff + jitter. 500 og 529 er også foreløbige; 400/401/403/404 er et anmodnings-/identitetsproblem og kan ikke løses ved at prøve igen. Et robust flow adskiller fejl i disse to grupper, forsøger et begrænset antal gange, overvåger grænsen forfra og viser rolige beskeder til brugeren.

Ansøgningsopgave

Overvej din integration. (1) Angiv de fejlkoder, du kan støde på, og adskil dem i "genprøves / permanent". (2) Skriv din eksponentielle tilbagetrækningsplan (initial hold, koefficient, cap, jitter) ned. (3) Angiv, hvordan du skal bruge gentag-efter-headeren. (4) Skriv den høflige besked, der skal vises til brugeren, når genforsøg er opbrugt.

tjekliste

  • [ ] Jeg kan forklare RPM/ITPM/OTPM-grænser og 429.
  • [ ] Jeg kan anvende logikken i eksponentiel tilbagetrækning + jitter + genforsøg-efter.
  • [ ] Jeg kan klassificere fejlkoder som genprøvelige/permanente.
  • [ ] Jeg ved, at vi ikke bør prøve enhver fejl.
  • [ ] I stedet for en rå fejl, kan jeg vise brugeren en rolig, handlingsorienteret besked.