Implementoval jsem škrcení pro chudého muže v phunction když používám pouze APC, používám to takto:
// 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));
}
Používám to na svém předním ovladači a předávám hodnotu své metodě směrování, ale to je jiný příběh.
Pointa je, že pokud používáte APC, jste schopni udržet věci velmi rychle v paměti as malou spotřebou paměti, protože APC se řídí metodikou FILO. Pokud potřebujete mnohem vyšší časové limity, můžete zvážit použití něčeho, co není založeno na paměti.
BTW:MySQL podporuje tabulky s modulem MEMORY.
Problém s sleep()
:
Typický webový server Apache s PHP nainstalovaným jako modul spotřebuje asi 10 MB RAM na instanci, abyste se vyhnuli překročení dostupné RAM, existují některá nastavení Apache, která můžete nakonfigurovat tak, abyste omezili maximální počet instancí, které je Apache schopen spustit.
Problém je, když sleep()
, tato instance je stále aktivní a s dostatečným počtem požadavků by mohla skončit sežráním všech dostupných slotů pro spuštění nových serverů, čímž by se váš web stal nedostupným, dokud nebudou dokončeny některé nevyřízené požadavky.
Z PHP AFAIK to nelze nijak překonat, takže je to nakonec na vás.
Princip je stejný pro celosystémové škrcení:
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;
}