Blog

Estábamos limitando la tasa de nuestros propios servicios

La API de Mythex permite 300 peticiones por minuto desde una misma dirección de red. Ese límite existe para protegernos de una sola persona o script que martillee la API. En producción empezó a rechazar a nuestros propios servicios, es decir, la parte de nuestro edge que sirve las apps publicadas y el servicio que ejecuta el agente de IA, porque cada uno de ellos llama a la API desde solo unas pocas direcciones. Las peticiones que llevan nuestra credencial interna ahora están exentas, y todo lo demás sigue limitado exactamente igual que antes.

El síntoma

La API empezó a responder con 429 Too Many Requests a algunas de nuestras propias llamadas internas. Se vieron afectados tres tipos de llamada, y cada uno importa a alguien que usa Mythex:

  • Buscar qué app vive en un dominio personalizado. Cuando un visitante abre una app publicada en su propio dominio, nuestro edge pregunta a la API dónde está ese sitio. Un 429 ahí es un visitante que no puede llegar a un sitio.
  • Guardar un turno del agente en ejecución. Mientras el agente trabaja, su progreso se guarda a medida que avanza, para que una respuesta sobreviva a un refresco o a una conexión caída. Un 429 ahí es progreso que no se guardó.
  • Comprobar el acceso a una vista previa. La vista previa de una app que estás construyendo está protegida, y el control pregunta a la API. Un 429 ahí es una vista previa que no se abre.

Ninguna de estas llamadas era una persona hablando con la API. Todas éramos nosotros.

Por qué pasaba

Un límite de peticiones por dirección hace una suposición: una dirección equivale aproximadamente a un solo cliente. Para las personas, eso basta. Para nuestra propia infraestructura, es muy erróneo.

  • El servicio de edge que sirve las apps publicadas y las vistas previas llama a la API desde unas pocas direcciones de salida compartidas. Cada visitante de cada app publicada y cada comprobación de vista previa llega como si viniera de una de esas pocas.
  • El orquestador, el servicio que ejecuta los turnos del agente, llama a la API desde una única dirección de contenedor. Cada turno en ejecución, para cada usuario, comparte esa dirección.

El presupuesto pensado para una persona se repartía entre todo el tráfico de un servicio entero. Esos servicios lo agotaron entre ellos, y el limitador hizo lo que se le había dicho: los rechazó.

La solución

Nuestros propios servicios ya demuestran quiénes son. Cada llamada interna lleva un token interno, y cada ruta bajo la sección interna de la API comprueba ese token antes de hacer nada.

El limitador de peticiones ahora usa la misma comprobación. Una petición cuyo token coincide con el interno está en una lista de permitidos y no cuenta contra el presupuesto por dirección. Todo lo demás se cuenta exactamente como antes: 300 peticiones por minuto por dirección.

Dos detalles impidieron que esto se convirtiera en un agujero:

  1. Un token incorrecto no obtiene ningún pase. La lista de permitidos solo coincide con el token interno real. Una petición con un token inventado se cuenta y se limita como cualquier otra, y las rutas internas la rechazan igualmente con 401 Unauthorized.
  2. El límite en sí no cambió. No subimos el número para hacer sitio. Subirlo habría ocultado el problema hasta que el tráfico volviera a crecer, y habría debilitado la protección para el caso que el límite existe para cubrir.

Movimos la configuración del limitador a una pequeña función y escribimos pruebas contra ella. Una envía 20 peticiones con el token interno a un limitador configurado para permitir 5, y espera que las 20 tengan éxito. Otra envía peticiones normales desde una dirección y espera que las cinco primeras tengan éxito y que las siguientes sean rechazadas. Una tercera envía peticiones con un token falsificado y espera que sean rechazadas del mismo modo.

Lo que aprendimos

  • Los límites llevan suposiciones. «Una dirección, un cliente» está integrado en un límite por dirección. Deja de ser cierto en cuanto tus propios servicios están detrás de direcciones compartidas, y muchos lo están: balanceadores de carga, redes de borde, contenedores, redes de oficina.
  • Distingue tu propio tráfico por identidad, no por dirección. Las direcciones son por donde llega el tráfico, no quién lo envió. Ya teníamos una credencial que demuestra que una llamada es nuestra; el limitador simplemente no la estaba mirando.
  • No lo arregles subiendo el número. Un límite más alto habría hecho desaparecer los 429 durante un tiempo, habría protegido menos y habría vuelto a fallar más tarde.
  • Mira quién está siendo limitado. Un 429 que cae sobre tu propio servicio es un informe de error sobre tus límites, no una señal de que el limitador funciona.

Qué significa si construyes sobre Mythex

No tienes que cambiar nada. Las apps publicadas en dominios personalizados, los turnos del agente y las vistas previas ya no dependen de lo ocupado que esté el resto de Mythex. El tráfico de tu app es asunto de tu app: el límite descrito aquí está en nuestra API, no en las apps que publicas.

Si tienes tu propio backend, la misma trampa se aplica a cualquier límite de peticiones que añadas. Nuestras guías sobre qué es una API y la lista de comprobación de seguridad para apps creadas con IA son un buen punto de partida. Y para otro caso en el que nuestra propia infraestructura se estorbaba, consulta cómo bajamos los despliegues a cero errores 502.

Mythex · Pricing · Crea lo que quieras con IA · Plantillas de sitios web y apps · Mythex comparado · Glosario para crear apps con IA · Herramientas gratis para crear apps con IA · English

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