2016-01-03 46 views
0

因此,我正在從API請求數據。 到目前爲止,我的API密鑰限制爲:如何觀察PHP中的費率限制?

10個請求每10秒 500請求每10分鐘

Bascially,我想從每場比賽的用戶起到請求特定的值。例如,這就是大約300場比賽。

所以我必須用我的PHP做300個請求。我如何減慢速度以觀察速率限制? (它可能需要時間,網站不一定要快)

我試過sleep(),這導致我的腳本崩潰..任何其他方式來做到這一點?

+0

'sleep()'在正確使用時不會使腳本崩潰。再看看'usleep()', – mblaettermann

+0

這個幫忙嗎? http://stackoverflow.com/questions/1375501/how-do-i-throttle-my-sites-api-users –

+0

此外,你應該以某種方式處理速率限制錯誤,只在需要或類似情況下進入休眠狀態。如果您達到費率限制,您會被阻止多久? 你也可以做一些時間計算,並在每次請求後調整你的睡眠時間,讓你的方法更進一步 – mblaettermann

回答

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

不需要Laravel或Cronjob。基本的睡眠應該足夠了。 – mblaettermann

+0

你可以在php中實現這樣一個持久的方案。有用。唯一可能造成輕微缺點的是在發生故障時沒有恢復。這在使用cron作業時會有所不同:只需啓動一個新的進程即可。 –

+0

「我建議設置一個每10秒執行一次的cron作業」這在技術上是不可能的。 – ceejayoz

-1

個別要求不減速。

相反,您通常會使用類似Redis的內容來跟蹤每個IP或每個用戶的請求。一旦限制達到一段時間,拒絕(也許使用HTTP 429狀態碼),直到計數重置爲止。

http://redis.io/commands/INCR加上http://redis.io/commands/expire很容易做到這一點。

+0

OP不寫他們正在實現的API。請求的答案應該描述如何遵守他們的請求的速率限制,而不是如何限制所有請求的速率限制。 –

+0

@ColinSchoen相同的技術可用於傳出請求。 – ceejayoz

0

這聽起來像是一個完美的使用set_time_limit() function。該功能允許您指定腳本可以在幾秒鐘內執行的時間。例如,如果您在腳本的開頭說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() function。正如對代碼的評論所指出的那樣,該函數只允許腳本忽略用戶中止,因此如果用戶在腳本仍在執行時關閉瀏覽器(或連接),則腳本將繼續檢索並處理來自無論如何API。你可能想在你的實現中禁用它,但是我會把它留給你。

顯然這段代碼是非常不完整的,但它應該給你一個正確的理解,你可以如何實現這個問題的解決方案。