PHP Redis 限制API和各种接口 请求频率

以下应该在几个场景:
①多长时间内限制用户操作一次 使用命令:sadd expire
②多长时间内限制用户操作多少次 使用命令:ttl incr setex

$supply = isset($_POST['supply']) ? $_POST['supply'] : '';
//这个key记录三方标识
$key = "request_limit_".$supply;
//限制请求时间内
$time = 3;
//限制次数为100
$limit = 100;

//下面出现的问题是,key处于临界值时,进入if操作后,key过期,这时key incr将导致该key永远不会过期,可以在限制里加上判断
$check = $redis->exists($key);//用于检查key是否存在
if($check){
    $count = $redis->incr($key);
    if($count > $limit){
        exit('您在{$time}秒内已经请求超过最大次 数,请稍后重试');
    }
}else{
    $redis->incr($key);
    //限制时间为time秒
    $redis->expire($key,$time);//设置key的过期时间可能下次key又进来了
}

//API业务逻辑 
echo '
'; ...

对比改进,并发的作用

$supply = isset($_POST['supply']) ? $_POST['supply'] : '';
//这个key记录三方标识
$key = "request_limit_".$supply;
//限制请求时间内
$time = 3;
//限制次数为100
$limit = 100;

$check = $redis->ttl($key); //-1,未设置过期, -2 不存在 ; >1 超过1秒
if($check > 0){//0.1进来的,进来后过期又重新设置,成永久key,ttl判断为-1
    $count = $redis->incr($key);
    if($count > $limit){
        exit('您在{$time}秒内已经请求超过最大次数,请稍后重试');
    }
}else{
    $redis->setex($key,$time,1);//过期重新设置该值
}
单个用户下单频率控制 利用sadd,当向集合中添加相同元素时返回0  设置控制时间 比如3秒内不能多次下单
                        判断ttl($key)时间  -2key不存在 -1未设置过期时间 
                        $result = $this->_reConnect->sAdd($key, $uid);
                if ($this->_reConnect->ttl($key) == -1) {
                 $this->_reConnect->expire($key, 3);
                         }
                  return $result;

下单总量控制  单位秒内总下单量不能超过一定范围
                                $key = Constant::TOTAL_USER_MAKE_ORDER;
                    $ttl = $this->_reConnect->ttl($key);
                    if ($ttl <= 0 || $ttl > 1 ) {   //-1,未设置过期, -2 不存在 ; >1 超过1秒
                        $result = $this->_reConnect->setEx($key, 1, 1);
                    } else {
                        $result = $this->_reConnect->incr($key);
                    }        
                    
                    return (int)$result;

初次设置key的时候加上过期时间。
   $rs = $this->_reConnect->incr($key);
        if ($rs == 1) {
            $exp = 86400 * 15;
            $this->_reConnect->expire($key, $exp);
        }

你可能感兴趣的:(PHP Redis 限制API和各种接口 请求频率)