Unité 8 / 11

Limites de vitesse et gestion résiliente des erreurs

Gains :

  • Peut interpréter les limites de vitesse (RPM/ITPM/OTPM) et les erreurs 429
  • Implémente une interruption exponentielle et une nouvelle tentative avec retry-after
  • Classifie et gère correctement les codes d'erreur HTTP courants (400/401/429/500/529)

Dans un environnement de production, aucune API ne répond parfaitement à tout moment. Parfois, vous envoyez des demandes trop rapidement et atteignez la limite ; parfois le serveur est temporairement occupé ; Parfois, votre demande est erronée dès le début. Ce qui distingue une intégration solide d’une tentative amateur, c’est qu’elle gère ces situations de manière prédictive et automatique. Dans cette unité, vous découvrirez les limites de débit (RPM/ITPM/OTPM), l'erreur 429, les nouvelles tentatives avec intervalle exponentiel et la classification appropriée des codes d'erreur HTTP courants. L’objectif : construire un flux si robuste qu’un utilisateur ne le remarquera jamais.

Que sont les limitations de vitesse ?

Le fournisseur limite la quantité de travail qu'un commutateur peut effectuer sur une période de temps donnée. Cette protection; Il protège à la fois l’infrastructure et vous-même des explosions soudaines des coûts. Il existe trois types courants de limites :

  • RPM (Requests Per Minute) : Nombre de requêtes par minute.
  • ITPM (Input Tokens Per Minute) : jeton d'entrée pouvant être traité par minute.
  • OTPM (Output Tokens Per Minute) : jeton de sortie pouvant être produit par minute.

Si vous dépassez l'une de ces limites, le fournisseur rejette la demande et renvoie un code d'erreur 429. Les limites varient généralement en fonction du niveau de votre compte (niveau) et peuvent être augmentées au fil du temps.

Astuce : Vous pouvez voir quand vous approchez de la limite à partir des en-têtes de réponse. La plupart des fournisseurs signalent votre quota restant avec des en-têtes tels que x-ratelimit-remaining-*. Surveiller ces valeurs et limiter le trafic devant est le moyen le plus mature de prévenir le problème sans obtenir un 429.

429 et retracement exponentiel

429 (limite de débit) est une erreur temporaire qui peut être réessayée. La bonne réponse est d'attendre la demande pendant un moment et de réessayer. Mais une attente constante ne suffit pas ; Si tout le monde réessaye en même temps, la limite sera à nouveau atteinte. La solution est une interruption exponentielle : augmenter le temps d'attente de manière exponentielle à chaque tentative échouée.

# Essai logique d'attente exponentielle 1 → 429 → attendre 1 seconde, essai 2 → 429 → attendre 2 secondes, essai 3 → 429 → attendre 4 secondes, essai 4 → 429 → attendre 8 secondes (+ petite "gigue" aléatoire)... abandonnez et faites un rapport après au plus N essais

L'ajout d'un peu de caractère aléatoire (gigue) à cela empêche les requêtes d'entrer en collision lorsque vous essayez de réessayer en même temps. De plus, la réponse 429 comporte souvent un en-tête « réessayer après » : « réessayez dans ce nombre de secondes ». Respecter ce titre est plus précis que d'attendre aveuglément.

Attention : lorsque vous recevez un 429, « le forcer en envoyant plus de requêtes » ne fera qu'empirer la situation ; La limite continue d'être remplie et aucune demande n'est acceptée. La bonne réponse est le retrait et non l’accélération. Bonne nouvelle : la plupart des SDK officiels réessayent automatiquement les erreurs 429 et le serveur avec une interruption : utilisez ce comportement du SDK avant de l'installer manuellement.

Classification des codes d'erreur HTTP

Toutes les erreurs ne sont pas identiques. Distinction critique : peut-il être réessayé ou s'agit-il d'un problème de demande/d'identité ?

Coder

Signification

Peut-on réessayer ?

réponse correcte

400

Requête invalide (erreur de format/paramètre)

non

Corrigez la demande ; n'envoie plus la même chose

401

Erreur d'authentification (clé invalide/manquante)

non

Corriger la clé/le titre

403

Aucune autorisation (pas d'accès au modèle/fonctionnalité)

non

Vérifier les autorisations/portée

404

Introuvable (ID de modèle/point de terminaison incorrect)

non

ID/adresse du modèle correct

429

Limite de vitesse dépassée

Oui

Retrait + réessai après

500

Erreur de serveur

Oui

Réessayez avec retraite

529

Serveur surchargé

Oui

Réessayez avec retraite

Règle d'or : 429, 500 et 529 sont temporaires ; On réessaye avec retrait. 400, 401, 403, 404 sont des problèmes de demande/identité ; Réessayer ne résoudra pas le problème et cela gaspillera des efforts. Votre code doit faire la distinction entre ces deux groupes.

Étape par étape : appel durable

  1. Soumettez la demande. En cas de succès, continuez.
  2. Classez le code d'erreur. Peut-on réessayer ?
  3. Si c'est possible : suivez la nouvelle tentative, appliquez un recul exponentiel + une gigue, essayez un nombre limité de fois (par exemple 5 max).
  4. Si vous n'avez pas essayé : corrigez (format/clé) et arrêtez ; Ne répétez pas la même requête erronée dans la boucle.
  5. Pensez à abandonner. Si l'opération échoue toujours après n tentatives, affichez un message poli à l'utilisateur et enregistrez l'événement (unité de suivi 11).

# Appel robuste pseudo-codedene = 0repeat : réponse = request_at() si réponse.succès : renvoie la réponse si réponse.code dans [429, 500, 529] et essaie < 5 : attend = retry_after ?? (2 ^ essayez sec + gigue) sleep (attendez); essayez += 1 ; git à nouveau si réponse.code dans [400, 401, 403, 404] : save_error(response); return "la demande doit être corrigée" return "erreur permanente, essayez plus tard"

# Commentaires polis à l'utilisateur (lorsque les tentatives sont épuisées) "Je suis occupé en ce moment, je n'ai pas pu traiter votre demande. Réessayez bientôt, ou j'ai enregistré votre demande, je vous répondrai quand elle sera prête."

Invite faible / Invite forte (ici : conception du message d'erreur)

# FAIBLE (affiche une erreur brute à l'utilisateur) "Erreur 429 : rate_limit_error"

# FORT (convivial, rassurant, suggérant des actions) "Il y a eu une congestion temporaire dans le système. Nous avons reçu votre demande en toute sécurité et elle est réessayée automatiquement. Si un résultat n'apparaît pas dans quelques secondes, vous pouvez actualiser la page."

Révéler l’erreur technique brute à l’utilisateur final sape la confiance et peut constituer une faille de sécurité. Catégoriser les erreurs en interne et transmettre à l'utilisateur un message calme et orienté vers l'action ; écrivez simplement les détails techniques pour le dossier.

Trois mini-étuis

Cas 1 — Un bateau s'est écrasé lors d'une explosion de circulation. Un robot du service client a reçu une augmentation de trafic de 429 le jour de la campagne ; Il n'y a eu aucune nouvelle tentative dans le code, chaque erreur a été reflétée directement à l'utilisateur comme une "erreur". Ils ont ajouté un retracement exponentiel + une nouvelle tentative après ; avec le même trafic, les requêtes ont été transmises avec un retard de plusieurs secondes, l'utilisateur n'a vu aucune erreur.

Cas 2 — Essayer 400 dans la boucle. Une intégration obtenait un 404 en raison d'un ID de modèle non valide, mais traitait toutes les erreurs comme « transitoires » et réessayait dans une boucle infinie ; Le journal a gonflé et une charge inutile a été créée. Ils ont ajouté une classification des erreurs : 404 est considéré comme permanent, la boucle est arrêtée et l'ID du modèle est corrigé. Leçon : ne réessayez pas toutes les erreurs.

Cas 3 — Gérer la limite de face. Un travail d'enrichissement des données s'exécutait en permanence à la limite 429. Ils ont suivi l'en-tête x-ratelimit-remaining et ont limité le trafic en fonction du quota. Ils ont donc gardé un rythme soutenu juste en dessous de la limite, sans prendre de 429 ; Le travail a été effectué de manière plus prévisible et plus rapide.

Erreurs courantes

  • Augmentation de la vitesse en 429 : aggrave la situation ; Passez à la retraite.
  • Réessayer chaque erreur : 400/401/404 est permanent ; Réessayer est du gaspillage.
  • Utilisation d'une attente fixe : crée une collision ; Utilisez exponentielle + gigue.
  • Ignorer « réessayer après » : il est plus précis de respecter le délai spécifié par le fournisseur.
  • Révéler l'erreur brute à l'utilisateur : ébranle la confiance, crée des vulnérabilités ; Classer à l'intérieur.
  • Nouvelles tentatives illimitées : définissez une limite supérieure (par exemple, 5 tentatives) ; puis abandonnez gracieusement.

Plus profond : file d'attente, concurrence et disjoncteurs

La persistance d’un seul désir est la première étape ; La vraie maturité est de gérer un grand nombre de demandes sans atteindre les limites. Trois concepts entrent ici en jeu.

File d'attente : vous placez les demandes dans une file d'attente pour les envoyer à un rythme contrôlé plutôt qu'immédiatement. La file d'attente atténue les pics soudains de trafic : même si 1 000 demandes arrivent en même temps, la file d'attente les libère à un rythme inférieur à la limite. De cette façon, vous évitez 429, vous n'avez alors pas à vous soucier de le réparer.

Limite de concurrence : vous limitez le nombre de requêtes "en cours" en même temps. Les requêtes parallèles illimitées remplissent rapidement les limites RPM et TPM. Un plafond de simultanéité raisonnable (par exemple pas plus de 10 requêtes simultanées) maintient les limites et rend le système prévisible.

Disjoncteur : si le fournisseur continue de renvoyer 500/529, au lieu d'essayer obstinément chaque demande, vous « coupez le circuit » pendant un certain temps et faites échouer rapidement la demande sans jamais l'envoyer. Après une attente, vous rallumez le circuit et essayez. Ce modèle empêche votre système de planter en cas de panne temporaire du fournisseur.

Ensemble, ces trois éléments établissent une résilience au niveau du système au-delà de la logique de nouvelle tentative d'un seul appel. À petite échelle, la nouvelle tentative automatique du SDK est suffisante ; À mesure que l’échelle augmente, la mise en file d’attente, la concurrence et le disjoncteur deviennent indispensables. Ils ont tous le même objectif commun : refléter un problème temporaire à l'utilisateur non pas comme un crash, mais comme un retard invisible de quelques secondes.

En résumé

429 revient lorsque les limites de vitesse (RPM/ITPM/OTPM) sont dépassées ; Il s'agit d'une erreur temporaire qui sera réessayée en utilisant la nouvelle tentative après et l'intervalle exponentiel + gigue. 500 et 529 sont également provisoires ; 400/401/403/404 est un problème de demande/identité et ne peut pas être résolu en réessayant. Un flux robuste sépare les erreurs en ces deux groupes, essaie un nombre limité de fois, surveille la limite de face et affiche des messages calmes à l'utilisateur.

Tâche de candidature

Pensez à votre intégration. (1) Répertoriez les codes d'erreur que vous pourriez rencontrer et séparez-les en « réessayable / permanent ». (2) Notez votre plan de retrait exponentiel (maintien initial, coefficient, plafond, gigue). (3) Spécifiez comment utiliser l'en-tête retry-after. (4) Écrivez le message de politesse à afficher à l'utilisateur lorsque les tentatives sont épuisées.

liste de contrôle

  • [ ] Je peux expliquer les limites RPM/ITPM/OTPM et 429.
  • [ ] Je peux appliquer la logique du retrait exponentiel + gigue + réessai après.
  • [ ] Je peux classer les codes d'erreur comme réessayables/permanents.
  • [ ] Je sais que nous ne devrions pas tenter toutes les erreurs.
  • [ ] Au lieu d'une erreur brute, je peux montrer à l'utilisateur un message calme et orienté vers l'action.