滑動窗口短信發送限流算法
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; }