2

私はこれを思いつきました:

if($prog->memcache) {
    $r = $prog->memcache->get("ratelimit:{$_SERVER['REMOTE_ADDR']}");
    if(!empty($r)) $prog->errorClose('この IP は悪用の可能性があるとフラグが立てられています。');
}

フー(); // レート制限しているもの...

if($prog->memcache)
    $prog->memcache->set("ratelimit:{$_SERVER['REMOTE_ADDR']}", 1, 0, 5);

IPがMemcachedで見つかった場合、数秒間スリープすることは有益でしょうか?

4

2 に答える 2

1

おそらく、IPアドレスの代わりにsession_id()を使用できますが、かなり良い解決策のようです。このようにして、ルーターの背後にいる人を扱っている場合、ハンマーを鳴らしていない人をブロックしません. session_id は、Cookie をクリアすることで簡単に再生成できますが、5 秒待つよりも時間がかかる可能性があります。スリープ中に PHP プロセスを保持するだけなので、PHP スクリプトでスリープすることは絶対に避けてください。

別の memcache アイテムを設定して、たとえば 1 時間以内に警告が表示された回数を追跡し、さらに厳しいことを行ったり、ユーザー情報をログに記録したりできます。

ただし、コストがかからないように操作を最適化するのが最善かもしれません(言うは易く行うは難しです)。

于 2010-03-25T14:59:04.437 に答える
0

レート制限にトークン バケット アルゴリズムを使用できます。私はあなたのためにそれを実装しました: bandwidth-throttle/token-bucket

サーバーのリソースをブロックするため、スリープしないこともお勧めします。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();
于 2015-07-12T18:51:01.153 に答える