转载: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); } }