Блог

Мы ограничивали собственные сервисы по частоте запросов

API Mythex допускает 300 запросов в минуту с одного сетевого адреса. Это ограничение существует, чтобы защитить нас от одного человека или скрипта, который засыпает API запросами. В продакшене оно начало отказывать нашим собственным сервисам — части нашего edge, которая отдаёт опубликованные приложения, и сервису, который запускает AI-агента, — потому что каждый из них обращается к API лишь с небольшого числа адресов. Теперь запросы с нашим внутренним ключом освобождены от ограничения, а все остальные ограничиваются точно так же, как раньше.

Симптом

API стал отвечать на некоторые наши внутренние вызовы кодом 429 Too Many Requests. Попали под это три типа вызовов, и каждый важен для тех, кто пользуется Mythex:

  • Поиск того, какое приложение живёт на собственном домене. Когда посетитель открывает опубликованное приложение на его домене, наш edge спрашивает API, какой это сайт. Ошибка 429 здесь — это посетитель, который не может открыть сайт.
  • Сохранение хода работающего агента. Пока агент работает, его прогресс сохраняется по ходу, чтобы ответ пережил обновление страницы или разорванное соединение. Ошибка 429 здесь — прогресс, который не сохранился.
  • Проверка доступа к превью. Превью приложения, которое вы создаёте, закрыто, и этот замок обращается к API. Ошибка 429 здесь — превью, которое не открывается.

Ни один из этих вызовов не был обращением людей к API. Все они были нашими.

Почему так вышло

Ограничение числа запросов с одного адреса делает одно допущение: один адрес — примерно один вызывающий. Для людей это почти верно. Для нашей собственной инфраструктуры — сильно нет.

  • Сервис edge, который отдаёт опубликованные приложения и превью, обращается к API с нескольких общих исходящих адресов. Каждый посетитель каждого опубликованного приложения и каждая проверка превью выглядят так, будто пришли с одного из этих немногих адресов.
  • Оркестратор — сервис, который запускает ходы агента, — обращается к API с одного адреса контейнера. Каждый работающий ход, для каждого пользователя, использует один и тот же адрес.

Таким образом бюджет, рассчитанный на одного человека, делился на весь трафик целого сервиса. Эти сервисы исчерпывали его между собой, и ограничитель сделал то, что ему велели: отказал им.

Исправление

Наши собственные сервисы и так доказывают, кто они. Каждый внутренний вызов несёт внутренний токен, и каждый маршрут во внутреннем разделе API проверяет этот токен, прежде чем что-либо делать.

Теперь ограничитель использует ту же проверку. Запрос, токен которого совпадает с внутренним, попадает в список разрешённых и не учитывается в бюджете на адрес. Всё остальное считается ровно так же, как раньше: 300 запросов в минуту на адрес.

Две детали не дали этому стать дырой:

  1. Неверный токен пропуска не получает. Список разрешённых совпадает только с настоящим внутренним токеном. Запрос с выдуманным токеном учитывается и ограничивается как любой другой, а внутренние маршруты по-прежнему отвергают его с 401 Unauthorized.
  2. Само ограничение не менялось. Мы не подняли число, чтобы освободить место. Повышение скрыло бы проблему до следующего роста трафика и ослабило бы защиту в том случае, ради которого ограничение существует.

Мы вынесли настройки ограничителя в одну небольшую функцию и написали тесты к ней. Один отправляет 20 запросов с внутренним токеном на ограничитель, настроенный на 5, и ожидает, что все 20 пройдут. Другой отправляет обычные запросы с одного адреса и ожидает, что первые пять пройдут, а следующие будут отклонены. Третий отправляет запросы с подделанным токеном и ожидает, что они будут отклонены так же.

Что мы из этого вынесли

  • У ограничений есть допущения. «Один адрес — один вызывающий» заложено в ограничение на адрес. Оно перестаёт быть верным, как только ваши собственные сервисы сидят за общими адресами — а так бывает часто: балансировщики нагрузки, edge-сети, контейнеры, офисные сети.
  • Отличайте свой трафик по идентичности, а не по адресу. Адрес — это то, как трафик приходит, а не то, кто его отправил. У нас уже был ключ, который доказывает, что вызов наш; ограничитель просто на него не смотрел.
  • Не решайте это повышением числа. Большее ограничение убрало бы ошибки 429 на время, защищало бы меньше и снова подвело бы позже.
  • Смотрите, кого ограничивают. Ошибка 429, которая попадает на ваш собственный сервис, — это сигнал о ваших лимитах, а не признак того, что ограничитель работает.

Что это значит, если вы строите на Mythex

Со своей стороны ничего менять не нужно. Опубликованные приложения на собственных доменах, ходы агента и превью больше не зависят от того, насколько загружен остальной Mythex. Трафик вашего приложения — дело вашего приложения: ограничение, о котором здесь речь, стоит на нашем API, а не на опубликованных вами приложениях.

Если у вас есть собственный бэкенд, та же ловушка касается любого ограничения частоты, которое вы добавите. Хорошая отправная точка — наши руководства что такое API и чек-лист безопасности для приложений, созданных с помощью AI. А про другой случай, когда наша собственная инфраструктура мешала сама себе, см. как мы добились нуля ошибок 502 при деплоях.

Mythex · Pricing · Создавайте что угодно с ИИ · Шаблоны сайтов и приложений · Сравнения Mythex · Глоссарий по созданию приложений с ИИ · Бесплатные инструменты для создания приложений с ИИ · 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) Română Slovenčina Slovenščina Soomaali Shqip Srpski Svenska Kiswahili தமிழ் తెలుగు ไทย Tagalog Türkçe Українська اردو Tiếng Việt 简体中文 繁體中文(香港) 繁體中文(台灣)