![](/img/trans.png)
[英]what is the best practice leaderboard with php, mysql, memcached?
[英]What's the best approach to rate limit an expensive operation with PHP & Memcached?
我想出了這個:
if($prog->memcache) { $r = $prog->memcache->get("ratelimit:{$_SERVER['REMOTE_ADDR']}"); if(!empty($r)) $prog->errorClose('This IP has been flagged for potential abuse.'); } foo(); // the thing we're rate limiting... if($prog->memcache) $prog->memcache->set("ratelimit:{$_SERVER['REMOTE_ADDR']}", 1, 0, 5);
對此有任何想法,如果在Memcached中找到IP,睡眠幾秒鍾是否有益?
似乎是一個很好的解決方案,盡管也許可以使用session_id()代替ip地址。 這樣,如果您與路由器背后的人打交道,就不會阻止那些不會重錘的人。 盡管可以通過清除cookie輕松地重新生成session_id,但這樣做可能要花更長的時間,而不僅僅是等待5秒鍾。 您絕對不想睡在PHP腳本中,因為那樣只會在睡着時阻止PHP進程。
您可以設置另一個內存緩存項,以跟蹤它們在1小時內達到警告次數的次數,然后您可以執行更苛刻的操作或記錄用戶信息。
盡管可能最好嘗試優化操作,以免成本高昂(說起來容易做起來難)。
您可以將令牌桶算法用於速率限制。 我已經為您實現了: 帶寬限制/令牌桶
我也建議不要睡眠,因為這會阻塞服務器資源。 只需使用HTTP狀態代碼429退出即可:
use bandwidthThrottle\tokenBucket\Rate;
use bandwidthThrottle\tokenBucket\TokenBucket;
use bandwidthThrottle\tokenBucket\storage\MemcachedStorage;
$storage = new MemcachedStorage("resource", $memcached);
$rate = new Rate(10, Rate::SECOND);
$bucket = new TokenBucket(10, $rate, $storage);
$bucket->bootstrap(10);
if (!$bucket->consume(1, $seconds)) {
http_response_code(429);
header(sprintf("Retry-After: %d", floor($seconds)));
exit();
}
foo();
但是,如果您真的想睡覺,可以使用BlockingConsumer
來做到這一點:
$consumer = new BlockingConsumer($bucket);
$consumer->consume(1);
foo();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.