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);
}
}
网友评论