貧乏人のスロットルメカニズム を実装しました phunction APCを単独で使用する場合、これが私が使用する方法です:
// allow 60 requests every 30 seconds
// each request counts as 1 (expensive operations can use higher values)
// keep track of IPs by REMOTE_ADDR (ignore others)
$throttle = ph()->Throttle($ttl = 30, $exit = 60, $count = 1, $proxy = false);
if ($throttle === true)
{
// IP exceded 30 requests in the last 60 seconds, die() here
}
else
{
// $throttle is a float
// number of requests in the last 30 seconds / 30 seconds
/*
1 req / 30 = 0,033 sec
5 req / 30 = 0,166 sec
10 req / 30 = 0,333 sec
15 req / 30 = 0,5 sec
20 req / 30 = 0,666 sec
25 req / 30 = 0,833 sec
30 req / 30 = 1 sec
*/
usleep(intval(floatval($throttle) * 1000000));
}
これをFront-Controllerで使用し、値をルーティングメソッドに渡しますが、それは別の話です。
結論として、APCを使用すると、APCはFILO手法に従っているため、メモリ内で非常に高速に、メモリ消費をほとんど必要とせずに物事を維持できます。はるかに長いタイムアウトが必要な場合は、メモリベースではないものを使用することを検討してください。
ところで:MySQLはMEMORYエンジンでテーブルをサポートしています。
sleep()
の問題 :
PHPがモジュールとしてインストールされている一般的なApacheWebサーバーは、インスタンスごとに約10 MBのRAMを消費します。使用可能なRAMを超えないように、Apacheが起動できるインスタンスの最大数を制限するように構成できるApache設定がいくつかあります。
問題は、sleep()
の場合です。 、そのインスタンスはまだアクティブであり、十分なリクエストがあると、新しいサーバーを起動するために利用可能なすべてのスロットを使い果たしてしまう可能性があります。そのため、保留中のリクエストが完了するまでWebサイトにアクセスできなくなります。
PHP AFAIKからこれを克服する方法はないので、最終的にはあなた次第です。
原理はシステム全体のスロットルについても同じです:
function systemWide($ttl = 86400, $exit = 360)
{
if (extension_loaded('apc') === true)
{
$key = array(__FUNCTION__);
if (apc_exists(__FUNCTION__) !== true)
{
apc_store(__FUNCTION__, 0, $ttl);
}
$result = apc_inc(__FUNCTION__, 1);
if ($result < $exit)
{
return ($result / $ttl);
}
return true;
}
return false;
}