滑动窗口短信发送限流算法
1.有两条规则
基于IP的限制和基于手机号的限制
IP规则:
1分钟限制5
10分钟限制30
1小时限制50
手机号规则:
1分钟限制1
10分钟限制5
1小时限制10
2.滑动窗口就是随着时间的流动 , 进行动态的删减区间内的数据 , 限制时获取区间内的数据
最主要的是用到了redis的zRemRangeByScore 来进行删除区间外的数据
<?php
/*滑动窗口短信发送限流算法
1.有两条规则
基于IP的限制和基于手机号的限制
IP规则:
1分钟限制5
10分钟限制30
1小时限制50
手机号规则:
1分钟限制1
10分钟限制5
1小时限制10
*/
//IP规则
$ipRules=array(
60=>5,
600=>30,
3600=>50
);
//手机号规则
$phoneRules=array(
60=>1,
600=>5,
3600=>10
);
$r = checkLimits($ipRules,$_SERVER["REMOTE_ADDR"],$_GET['tel']);
var_dump($r);
$r = checkLimits($phoneRules,$_GET['tel'],$_GET['tel']);
var_dump($r);
function checkLimits($rules,$key,$tel){
$redis = new Redis();
$redis->connect('115.159.28.111', 1991);
foreach($rules as $ruleTime=>$rule) {
$redisKey=$key."_".$ruleTime;
$score=time();
$member=$tel.'_'.$score;
$redis->multi();
$redis->zRemRangeByScore($redisKey, 0, $score - $ruleTime);//移除窗口以外的数据
$redis->zAdd($redisKey, $score, $member);
$redis->expire($redisKey, $ruleTime);
$redis->zRange($redisKey, 0, -1, true);
$members = $redis->exec();
if (empty($members[3])) {
break;
}
$nums=count($members[3]);
var_dump($nums);
if($nums>$rule){
return false;
}
}
return true;
}