Blog

Nous nous limitions nous-mêmes en débit

L'API de Mythex autorise 300 requêtes par minute depuis une même adresse réseau. Cette limite existe pour nous protéger d'une personne ou d'un script qui martèlerait l'API. En production, elle a commencé à refuser nos propres services — la partie de notre edge qui sert les applications publiées et le service qui exécute l'agent IA —, parce que chacun d'eux atteint l'API depuis seulement quelques adresses. Les requêtes qui portent notre identifiant interne sont désormais exemptées, et tous les autres appels restent limités exactement comme avant.

Le symptôme

L'API a commencé à répondre à certains de nos appels internes par 429 Too Many Requests. Trois types d'appels étaient touchés, et chacun compte pour quelqu'un qui utilise Mythex :

  • Recherche de l'application installée sur un domaine personnalisé. Quand un visiteur ouvre une application publiée sur son propre domaine, notre edge demande à l'API où se trouve ce site. Un 429 à cet endroit signifie un visiteur qui ne peut pas atteindre un site.
  • Enregistrement d'un tour d'agent en cours. Pendant que l'agent travaille, sa progression est enregistrée au fil de l'eau, afin qu'une réponse survive à une actualisation ou à une connexion coupée. Un 429 à cet endroit signifie une progression qui n'a pas été enregistrée.
  • Vérification de l'accès à un aperçu. L'aperçu d'une application en cours de construction est protégé, et ce contrôle interroge l'API. Un 429 à cet endroit signifie un aperçu qui ne s'ouvre pas.

Aucun de ces appels ne venait de personnes utilisant l'API. Ils venaient tous de nous.

Pourquoi cela arrivait

Une limite de débit par adresse repose sur une hypothèse : une adresse correspond à peu près à un appelant. Pour des personnes, c'est assez proche. Pour notre propre infrastructure, c'est fortement faux.

  • Le service edge qui sert les applications publiées et les aperçus atteint l'API depuis quelques adresses sortantes partagées. Chaque visiteur de chaque application publiée, et chaque vérification d'aperçu, arrive donc comme s'il venait d'une de ces quelques adresses.
  • L'orchestrateur — le service qui exécute les tours d'agent — atteint l'API depuis une seule adresse de conteneur. Chaque tour en cours, pour chaque utilisateur, partage cette adresse.

Le budget prévu pour une seule personne était donc réparti entre tout le trafic d'un service entier. Ces services l'ont épuisé à eux deux, et le limiteur a fait ce pour quoi il était configuré : il les a refusés.

La correction

Nos propres services prouvent déjà qui ils sont. Chaque appel interne transporte un jeton interne, et chaque route de la section interne de l'API vérifie ce jeton avant de faire quoi que ce soit.

Le limiteur de débit utilise désormais le même contrôle. Une requête dont le jeton correspond au jeton interne est placée sur une liste d'autorisation et n'est pas comptée dans le budget par adresse. Tout le reste est compté exactement comme avant : 300 requêtes par minute et par adresse.

Deux détails ont empêché que cela ne devienne une faille :

  1. Un mauvais jeton n'obtient aucun passe-droit. La liste d'autorisation ne correspond qu'au vrai jeton interne. Une requête avec un jeton inventé est comptée et limitée comme les autres, et les routes internes la rejettent avec 401 Unauthorized.
  2. La limite elle-même n'a pas changé. Nous n'avons pas relevé le chiffre pour faire de la place. Le relever aurait masqué le problème jusqu'à la prochaine hausse de trafic, et affaibli la protection pour le cas que la limite est censée couvrir.

Nous avons déplacé les paramètres du limiteur dans une petite fonction et écrit des tests sur celle-ci. L'un envoie 20 requêtes avec le jeton interne à un limiteur réglé sur 5, et attend que les 20 réussissent. Un autre envoie des requêtes simples depuis une même adresse et attend que les cinq premières réussissent et que celles d'après soient refusées. Un troisième envoie des requêtes avec un faux jeton et attend qu'elles soient refusées de la même manière.

Ce que nous en avons retenu

  • Les limites portent des hypothèses. « Une adresse, un appelant » est intégré à une limite par adresse. Cela cesse d'être vrai dès que vos propres services se trouvent derrière des adresses partagées — et beaucoup le sont : répartiteurs de charge, réseaux edge, conteneurs, réseaux de bureau.
  • Distinguez votre propre trafic par identité, pas par adresse. Les adresses sont la façon dont le trafic arrive, pas qui l'a envoyé. Nous avions déjà un identifiant qui prouve qu'un appel est le nôtre ; le limiteur ne le regardait tout simplement pas.
  • Ne réglez pas le problème en augmentant le chiffre. Une limite plus haute aurait fait disparaître les 429 pendant un temps, aurait protégé moins, et aurait échoué à nouveau plus tard.
  • Regardez qui est limité. Un 429 qui touche votre propre service est un signalement de bogue sur vos limites, pas la preuve que le limiteur fonctionne.

Ce que cela signifie si vous construisez sur Mythex

Rien à changer de votre côté. Les applications publiées sur des domaines personnalisés, les tours d'agent et les aperçus ne dépendent plus de l'activité du reste de Mythex. Le trafic de votre application est votre affaire : la limite décrite ici concerne notre API, et non les applications que vous publiez.

Si vous faites tourner votre propre backend, le même piège guette toute limite de débit que vous ajoutez. Nos guides sur ce qu'est une API et sur la liste de contrôle de sécurité pour les applications construites avec l'IA sont un bon point de départ. Pour un autre cas où notre propre infrastructure s'est mise en travers de son chemin, voir comment nous sommes arrivés à zéro erreur 502 lors des déploiements.

Mythex · Pricing · Créez tout avec l'IA · Modèles de sites et d'applications · Mythex comparé · Glossaire de la création d'applications avec l'IA · Outils gratuits pour créer des applications avec l'IA · English

English አማርኛ العربية Български বাংলা Bosanski Català Čeština Dansk Deutsch Ελληνικά Español Español (España) Eesti فارسی Suomi Français (Canada) ગુજરાતી हिन्दी Hrvatski Magyar Հայերեն Bahasa Indonesia Íslenska Italiano 日本語 ქართული Қазақ тілі ಕನ್ನಡ 한국어 Lietuvių Latviešu Македонски മലയാളം Монгол मराठी Bahasa Melayu မြန်မာ Norsk bokmål Nederlands ਪੰਜਾਬੀ Polski Português (Brasil) Português (Portugal) Română Русский Slovenčina Slovenščina Soomaali Shqip Srpski Svenska Kiswahili தமிழ் తెలుగు ไทย Tagalog Türkçe Українська اردو Tiếng Việt 简体中文 繁體中文(香港) 繁體中文(台灣)