Перейти к содержимому

Ограничение частоты запросов

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

Настройка ограничения частоты

Примените ограничение частоты при отправке задания:

PHP
use Queuety\Queuety;

Queuety::dispatch( 'call_openai', $payload )
    ->rate_limit( 10, 60 ); // max 10 executions per 60 seconds

Два аргумента означают:

  1. $max — максимальное число выполнений, разрешенных в окне
  2. $window — длительность окна в секундах

Ограничение, заданное при отправке, регистрируется только в процессе PHP, который отправляет задание. Обработчик, работающий в отдельном процессе, например wp queuety work, его не увидит. Поэтому ограничения, которые должны действовать между процессами, задавайте в config() обработчика, как показано ниже (#3).

Ограничения частоты на уровне обработчика

Задайте ограничения частоты в методе config() обработчика, чтобы они применялись при каждой отправке:

PHP
use Queuety\Handler;

class CallOpenAIHandler implements Handler {
    public function handle( array $payload ): void {
        // Call the API...
    }

    public function config(): array {
        return [
            'rate_limit' => [ 60, 60 ], // 60 requests per minute
        ];
    }
}

Как это работает

Ограничения частоты отслеживаются по имени обработчика. Забрав задание, обработчик регистрирует лимит обработчика (из его config()) и проверяет ограничитель частоты. Если обработчик достиг лимита, он сразу возвращает задание в pending без задержки и без расходования попытки, а затем ждет QUEUETY_WORKER_SLEEP секунд перед следующим опросом. Обработчик, запущенный с --once, вместо этого завершает работу.

Каждый обработчик хранит счетчик в памяти и каждые 5 секунд обновляет его из таблицы queuety_logs, подсчитывая записи журнала completed для обработчика за последние $window секунд. Поскольку подсчет ведется по общей таблице журналов (и общему кэшу, если он настроен), ограничения на уровне обработчика действуют во всех процессах обработчиков, а не только внутри одного обработчика. Неудачные выполнения не учитываются в лимите.

Программный доступ

Получите прямой доступ к ограничителю частоты:

PHP
$limiter = Queuety::rate_limiter();

// Register a rate limit
$limiter->register( 'call_openai', 60, 60 );

// Check whether a handler has reached its limit
$limited = $limiter->is_limited( 'call_openai' ); // true while the limit is reached

// Seconds until the current window resets
$wait = $limiter->time_until_available( 'call_openai' );

register() и is_limited() воздействуют на ограничитель в текущем процессе PHP. Регистрация ограничения здесь не меняет правила, применяемые отдельно запущенным обработчиком.

Сценарии использования

  • Внешние лимиты API. Согласуйте ограничение частоты с квотой API (e.g., 60 запросов в минуту у OpenAI).
  • Ограничение частоты отправки писем. Не допускайте отправки слишком большого количества писем за короткий промежуток времени.
  • Защита ресурсов. Ограничьте обработчики с интенсивной нагрузкой на CPU, чтобы они не лишали другие задания ресурсов.