转载:https://www.jianshu.com/p/d1326ab657ff

IP请求限制,之前用过redis的set设置时间戳一分钟过期;也用过nginx的IP限流配置。前者,没法解决“用户在一分钟之内,最后一秒访问了9次,又在下一分钟的第一秒访问了10次”的问题;后者,又被迫均匀到秒级。思考并和别人探讨了一番,得出下面的解决方案:用redis的队列解决。

1、IP为键,时间戳为值,创建队列

$redis->lpush($ip, time());

2、同IP再次访问,判断队列长度

$len = $redis->llen($ip);
if ( $len < 10 ) {
    $redis->lpush($ip, time());
}else{
    // doing
}

3、长度超限,若首尾时间差< 60阻止;>=60剔除队首元素

$len = $redis->llen($ip);
if ( $len < 10 ) {
    $redis->lpush($ip, time());
}else{
    $firstTime  = lindex($ip, -1);
    $nowTime    = time();

    if ( ($firstTime - $currentTimt) < 60 ){
        exit('超出限制');
    }else{
        $redis->lpush($ip, $nowTime);
        $redis->rpop($ip);
    }
}
01-21 02:16