Blog

Ne limitam singuri serviciile

API-ul Mythex permite 300 de cereri pe minut de la o adresă de rețea. Această limită există ca să ne protejeze de o singură persoană sau de un script care bombardează API-ul. În producție, a început să refuze propriile noastre servicii — partea din edge-ul nostru care servește aplicațiile publicate și serviciul care rulează agentul AI — pentru că fiecare dintre ele ajunge la API doar de la câteva adrese. Cererile care poartă credențialul nostru intern sunt acum scutite, iar toți ceilalți sunt limitați exact ca înainte.

Simptomul

API-ul a început să răspundă unor apeluri interne de-ale noastre cu 429 Too Many Requests. Au fost lovite trei tipuri de apeluri, și fiecare contează pentru cineva care folosește Mythex:

  • Căutarea aplicației care stă pe un domeniu personalizat. Când un vizitator deschide o aplicație publicată pe propriul domeniu, edge-ul nostru întreabă API-ul unde se află acel site. Un 429 acolo înseamnă un vizitator care nu poate ajunge la un site.
  • Salvarea unei ture de agent în desfășurare. Cât timp lucrează agentul, progresul său este salvat pe parcurs, ca un răspuns să supraviețuiască unei reîmprospătări a paginii sau unei conexiuni căzute. Un 429 acolo înseamnă progres nesalvat.
  • Verificarea accesului la un preview. Preview-ul unei aplicații pe care o construiești este protejat, iar acest filtru întreabă API-ul. Un 429 acolo înseamnă un preview care nu se deschide.

Niciunul dintre acestea nu erau persoane care apelau API-ul. Toate erau noi.

De ce s-a întâmplat

O limită pe adresă face o singură presupunere: o adresă înseamnă aproximativ un apelant. Pentru oameni, asta e destul de aproape de adevăr. Pentru propria noastră infrastructură, e foarte greșită.

  • Serviciul edge care servește aplicațiile publicate și preview-urile ajunge la API de la câteva adrese de ieșire partajate. Fiecare vizitator al fiecărei aplicații publicate și fiecare verificare de preview apare ca venind de la una dintre acele câteva adrese.
  • Orchestratorul — serviciul care rulează turele agentului — ajunge la API de la o singură adresă de container. Fiecare tură în desfășurare, pentru fiecare utilizator, împarte aceeași adresă.

Bugetul gândit pentru o singură persoană era astfel împărțit între tot traficul unui întreg serviciu. Serviciile acestea îl consumau împreună, iar limitatorul a făcut ce i se cerea: le-a refuzat.

Remedierea

Serviciile noastre interne își dovedesc deja identitatea. Fiecare apel intern poartă un token intern, iar fiecare rută din secțiunea internă a API-ului verifică acest token înainte să facă ceva.

Limitatorul de rată folosește acum aceeași verificare. O cerere al cărei token se potrivește cu cel intern este pe o listă de permisiuni și nu se numără în bugetul pe adresă. Tot restul se numără exact ca înainte: 300 de cereri pe minut pe adresă.

Două detalii au împiedicat transformarea asta într-o gaură de securitate:

  1. Un token greșit nu primește nicio excepție. Lista de permisiuni se potrivește doar cu tokenul intern real. O cerere cu un token inventat este numărată și limitată ca oricare alta, iar rutele interne o resping în continuare cu 401 Unauthorized.
  2. Limita în sine nu s-a schimbat. Nu am ridicat numărul ca să facem loc. Ridicarea lui ar fi ascuns problema până la următoarea creștere de trafic și ar fi slăbit protecția pentru cazul pentru care există limita.

Am mutat setările limitatorului într-o funcție mică și am scris teste pentru ea. Unul trimite 20 de cereri cu tokenul intern către un limitator setat să permită 5 și se așteaptă ca toate cele 20 să reușească. Altul trimite cereri obișnuite de la o adresă și se așteaptă ca primele cinci să reușească, iar cele următoare să fie refuzate. Un al treilea trimite cereri cu un token falsificat și se așteaptă ca acestea să fie refuzate în același mod.

Ce am învățat

  • Limitele poartă presupuneri. „O adresă, un apelant” este înscris în orice limită pe adresă. Încetează să fie adevărat în momentul în care propriile servicii stau în spatele unor adrese partajate — și multe stau: load balancere, rețele edge, containere, rețele de birou.
  • Deosebește traficul propriu după identitate, nu după adresă. Adresele arată cum ajunge traficul, nu cine l-a trimis. Aveam deja un credențial care dovedește că un apel este al nostru; limitatorul pur și simplu nu se uita la el.
  • Nu o repara ridicând numărul. O limită mai mare ar fi făcut erorile 429 să dispară pentru o vreme, ar fi protejat mai puțin și ar fi eșuat din nou mai târziu.
  • Uită-te la cine este limitat. Un 429 care lovește propriul tău serviciu este un raport de eroare despre limitele tale, nu un semn că limitatorul funcționează.

Ce înseamnă asta dacă construiești pe Mythex

Nu trebuie să schimbi nimic la tine. Aplicațiile publicate pe domenii personalizate, turele agentului și preview-urile nu mai depind de cât de aglomerat este restul Mythex. Traficul propriu al aplicației tale este treaba aplicației tale: limita descrisă aici se aplică API-ului nostru, nu aplicațiilor pe care le publici.

Dacă rulezi un backend propriu, aceeași capcană se aplică oricărei limite de rată pe care o adaugi. Ghidurile noastre despre ce este un API și lista de verificare a securității pentru aplicațiile construite cu AI sunt un bun punct de plecare. Iar pentru un alt caz în care infrastructura noastră s-a blocat singură, vezi cum am ajuns la zero erori 502 la deploy-uri.

Mythex · Pricing · Construiește orice cu AI · Șabloane pentru site-uri și aplicații · Mythex comparat · Glosar pentru crearea de aplicații cu AI · Instrumente gratuite pentru crearea de aplicații cu AI · English

English አማርኛ العربية Български বাংলা Bosanski Català Čeština Dansk Deutsch Ελληνικά Español Español (España) Eesti فارسی Suomi Français 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) Русский Slovenčina Slovenščina Soomaali Shqip Srpski Svenska Kiswahili தமிழ் తెలుగు ไทย Tagalog Türkçe Українська اردو Tiếng Việt 简体中文 繁體中文(香港) 繁體中文(台灣)