Лимиты потребления в PHP API защищают доступность сервиса и помогают контролировать его стоимость, но неудачно спроектированная политика может нарушить работу легитимных интеграций. Чтобы выбрать подходящий подход, недостаточно задать число запросов в минуту: нужно определить, кто потребляет ресурсы, какую операцию выполняет, какой ресурс находится под угрозой и как ведёт себя реальный трафик.
Эффективная система сочетает лимиты, соответствующие модели использования, согласованные счётчики между инстансами и ответы, позволяющие клиенту восстановить работу. Необходимо также наблюдать за эффектом правил до того, как ужесточать их, особенно если несколько клиентов используют общие учётные данные или зависят от общих ресурсов.
Различайте частоту запросов, квоты и параллельность

Эти механизмы защищают от разных проблем и не взаимозаменяемы:
- Частота запросов: ограничивает количество запросов, принимаемых за короткий интервал. Помогает сдерживать всплески или длительный интенсивный трафик, перегружающий приложение.
- Накопительная квота: ограничивает общее потребление за более длительный период, например число операций в день или расчётный период. Подходит для контроля использования в рамках тарифа или накопленных затрат на ресурсоёмкие операции.
- Параллельность: ограничивает число операций, выполняющихся одновременно. Полезна, когда каждая операция может надолго занимать workers, подключения или другие ресурсы.
Клиент может соблюдать ограничение частоты и при этом одновременно выполнять множество длительных операций; он также может отправлять мало запросов, расходующих значительную дневную квоту. Выбирайте механизм исходя из риска, который нужно снизить. Если требуется несколько механизмов, определите, как они взаимодействуют и какой из них применяется первым.
Определите, по какому идентификатору и ресурсу вводить ограничения
Ключ лимита должен соответствовать единице потребления, имеющей операционный смысл. В зависимости от продукта это могут быть учётные данные, пользователь, организация, клиентское приложение, маршрут или их комбинация. Ограничение только по IP-адресу может затронуть общие сети и плохо различает аутентифицированных потребителей; IP-адрес можно использовать как дополнительный сигнал для анонимного трафика или механизмов безопасности.
Для аутентифицированных клиентов целесообразно привязать политику к стабильному идентификатору и изолировать организации друг от друга. Если несколько систем используют общие учётные данные, бывает сложно определить, какая из них создала всплеск: по возможности используйте отдельные учётные данные или добавьте параметры, позволяющие отнести потребление к конкретному источнику. Не включайте секреты в исходном виде в ключи счётчиков или записи журналов.
Стоимость разных маршрутов неодинакова. Простой запрос и масштабный экспорт не обязательно должны расходовать один и тот же лимит. Для затратных операций можно задать веса или отдельные политики, если критерии понятны потребителям и применяются последовательно. Учитывайте также ограничения самого сервиса: API может получать мало запросов, но всё равно перегружать общую зависимость, например базу данных или внешнего поставщика.
Выбирайте временные окна с учётом модели использования
Фиксированное окно легко объяснить, но оно может допустить всплеск в конце одного интервала и ещё один в начале следующего. Скользящее окно уменьшает этот эффект, но требует больше ресурсов для хранения и вычислений. Алгоритм с токенами допускает ограниченные всплески при контролируемой средней частоте; он подходит, когда легитимный трафик поступает волнами. Выбор зависит от модели потребления и необходимой точности.
Не принимайте легитимный пик активности за злоупотребление. Запланированные задания, синхронизация в начале рабочего дня или повторные попытки после сбоя могут концентрировать запросы. Если продукт допускает всплески, явно задайте их размер и время восстановления квоты. Для длительных операций дополнительно ограничивайте параллельность или применяйте контроль допуска до того, как будут заняты дефицитные ресурсы.
Важно учитывать и повторные попытки клиента. Если временный ответ вызывает немедленные повторы, лимит может усилить пик. Рекомендуйте постепенно увеличивать интервалы ожидания, желательно со случайной вариацией, и определите, считаются ли повторные операции с одним и тем же ключом идемпотентности новыми запросами или безопасными повторами.
Согласуйте счётчики при работе PHP в нескольких инстансах
Счётчик, хранящийся только в памяти процесса, может работать в одном инстансе, но перестаёт быть согласованным при распределении трафика между несколькими инстансами. Каждый сервер может принять свою часть лимита, и суммарно он будет превышен. В системах с несколькими инстансами состояние необходимо согласовывать через общее хранилище или эквивалентный механизм с подходящими атомарными операциями.
Заранее определите поведение при сбоях системы счётчиков. Если она станет недоступна, отклонение всех запросов может прервать работу легитимных клиентов, а принятие всех запросов — подвергнуть риску критически важную зависимость. Решение зависит от риска, связанного с маршрутом: для малозатратного запроса может быть разумен один режим отказа, а для операции, вызывающей большие расходы, — другой. Задокументируйте выбранный подход и настройте оповещения о деградации.
Не используйте слишком общие ключи счётчиков, смешивающие организации или маршруты, и слишком раздробленные ключи, затрудняющие контроль общего потребления. Настройте срок действия и очистку состояния, чтобы временные ключи не накапливались бесконечно. Убедитесь, что изменения конфигурации не приводят к неожиданному сбросу или дублированию счётчиков.
Сделайте отказ частью контракта API
При достижении лимита возвращайте HTTP-статус, соответствующий контракту API — обычно 429 Too Many Requests при ограничении частоты, — и структурированное тело ответа с указанием типа лимита, но без раскрытия внутренней информации. Если операция отклонена по другой причине, не используйте этот статус так, чтобы вводить клиента в заблуждение.
Предоставьте полезные рекомендации по восстановлению работы, например предполагаемое время до следующей попытки или сведения о лимите и потреблении, предусмотренные контрактом. Если отправляете заголовок Retry-After, убедитесь, что он задаёт корректное время ожидания. Используйте единообразные ответы на разных маршрутах и не раскрывайте счётчики других клиентов. Потребители должны иметь возможность отличить временный отказ от ошибок аутентификации, валидации или доступности.
Наблюдайте за влиянием и корректируйте политику на основе данных
Регистрируйте принятые и отклонённые запросы, безопасно фиксируя идентификатор или сегмент клиента, маршрут, применённую политику и причину. Также измеряйте задержку, параллельность и нагрузку на важные зависимости. Не сохраняйте учётные данные и ненужные персональные данные; если для анализа достаточно, используйте защищённые идентификаторы или агрегированные данные.
Рост числа отказов сам по себе не доказывает, что порог слишком строгий. Ищите закономерности: какие клиенты затронуты, в какое время, на каких маршрутах, какова длительность операций и следуют ли за отказами повторные попытки. Проверяйте признаки ложных срабатываний, например скопление отказов у организаций с общими учётными данными или в запланированных заданиях. Меняйте по одной переменной за раз и сохраняйте возможность отменить изменение.
Внедряйте политику постепенно

До включения лимита оцените политику по данным об использовании и протестируйте репрезентативные сценарии. Если архитектура позволяет, регистрируйте запросы, которые были бы отклонены, не блокируя их; такое наблюдение не заменяет нагрузочное тестирование и не гарантирует, что исторические данные позволят предсказать все всплески.
- Определите риск, который нужно контролировать, и выберите ограничение частоты, квоту, параллельность или их сочетание.
- Назначьте лимиты по идентификатору и ресурсу и проверьте изоляцию пользователей и организаций.
- Протестируйте всплески, медленные операции, повторные попытки, общие учётные данные и сбои хранилища счётчиков.
- Убедитесь, что несколько инстансов применяют лимит согласованно, а временное состояние очищается.
- Проверьте ответ при отказе, рекомендации по повторной попытке и совместимость с текущими потребителями.
- Следите за отказами, задержкой и состоянием зависимостей; сообщайте об изменениях, которые могут повлиять на интеграции.
Лимиты потребления в PHP API должны защищать и платформу, и непрерывность работы клиентов. Лучшая политика — не самая строгая, а та, которая контролирует риск с помощью правил, позволяющих определить источник потребления, предсказуемых ответов и достаточных данных для устранения нежелательных последствий.



