Как мне соблюдать ограничение скорости в PHP?

Итак, я запрашиваю данные из API.
Пока мой ключ API ограничен:

10 запросов каждые 10 секунд
500 запросов каждые 10 минут

В сущности, я хочу запрашивать определенное значение в каждой игре, в которую играл пользователь.
Это, например, около 300 игр.

Поэтому я должен сделать 300 запросов с моим PHP. Как я могу замедлить их, чтобы соблюдать ограничение скорости?
(Это может занять время, сайт не должен быть быстрым)

Я попробовал sleep (), что привело к сбою моего скрипта. Есть ли другие способы сделать это?

0

Решение

Я предлагаю настроить работу cron, которая выполняется каждую минуту, или даже лучше использовать планирование Laravel, а не использовать sleep или usleep для имитации cron.

Вот некоторая информация об обоих:

https://laravel.com/docs/5.1/scheduling

http://www.cyberciti.biz/faq/how-do-i-add-jobs-to-cron-under-linux-or-unix-oses/

0

Другие решения

Это звучит как идеальное использование для set_time_limit() функция. Эта функция позволяет вам указать продолжительность выполнения скрипта в секундах. Например, если вы говорите set_time_limit(45); в начале вашего скрипта, то скрипт будет работать в общей сложности 45 секунд. Одной из замечательных особенностей этой функции является то, что вы можете позволить вашему скрипту выполняться бесконечно (без ограничения по времени), говоря: set_time_limit(0);,

Вы можете написать свой скрипт, используя следующую общую структуру:

<?php
// Ignore user aborts and allow the script
// to run forever
ignore_user_abort(true);
set_time_limit(0);

// Define constant for how much time must pass between batches of connections:
define('TIME_LIMIT', 10); // Seconds between batches of API requests

$tLast = 0;
while( /* Some condition to check if there are still API connections that need to be made */ ){

if( timestamp() <= ($tLast + TIME_LIMIT) ){ // Check if TIME_LIMIT seconds have passed since the last connection batch
// TIME_LIMIT seconds have passed since the last batch of connections
/* Use cURL multi to make 10 asynchronous connections to the API */

// Once all of those connections are made and processed, save the current time:
$tLast = timestamp();
}else{
// TIME_LIMIT seconds have not yet passed
// Calculate the total number of seconds remaining until TIME_LIMIT seconds have passed:
$timeDifference = $tLast + TIME_LIMIT - timestamp();
sleep( $timeDifference ); // Sleep for the calculated number of seconds
}

} // END WHILE-LOOP

/* Do any additional processing, computing, and output */
?>

Заметка: В этом фрагменте кода я также использую ignore_user_abort() функция. Как отмечено в комментарии к коду, эта функция просто позволяет сценарию игнорировать прерывание пользователя, поэтому, если пользователь закрывает браузер (или подключение) во время выполнения сценария, сценарий продолжит извлекать и обрабатывать данные из API в любом случае. Возможно, вы захотите отключить это в своей реализации, но я оставлю это на ваше усмотрение.

Очевидно, что этот код очень неполный, но он должен дать вам приличное понимание того, как вы могли бы реализовать решение этой проблемы.

0

Не замедляйте индивидуальные запросы.

Вместо этого вы обычно используете что-то вроде Redis для отслеживания запросов по IP или по каждому пользователю. Как только ограничение достигнет определенного периода времени, отклоните его (возможно, с кодом состояния HTTP 429), пока счетчик не будет сброшен.

http://redis.io/commands/INCR в сочетании с http://redis.io/commands/expire легко бы сделать свое дело.

-1
По вопросам рекламы [email protected]