[PHP] 基於redis實現滑動窗口式的短信發送接口限流


滑動窗口短信發送限流算法

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;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM