私はAPC だけを使用してphunctionに貧乏人のスロットリング メカニズムを実装しました。
// 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 がインストールされた典型的な Apache Web サーバーは、インスタンスごとに約 10 MB の RAM を消費します。使用可能な RAM を超えないようにするために、Apache が起動できるインスタンスの最大数を制限するように構成できる Apache 設定がいくつかあります。
問題はsleep()
、そのインスタンスがまだアクティブであり、十分なリクエストがあると、新しいサーバーを起動するために使用可能なすべてのスロットを消費してしまい、保留中のリクエストが完了するまで Web サイトにアクセスできなくなる可能性がある場合です。
PHPの知る限り、これを克服する方法はないため、最終的にはあなた次第です。
原則は、システム全体のスロットリングと同じです。
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;
}