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 '<br/>';
   ...

对比改进,并发的作用

$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);
        }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Redis从入门到精通:中级篇 本文目录 上一篇文章以认识Redis为主,写了Redis系列的第一篇,现在开启第二...
    叨唧唧的阅读 783评论 0 0
  • NOSQL类型简介键值对:会使用到一个哈希表,表中有一个特定的键和一个指针指向特定的数据,如redis,volde...
    MicoCube阅读 4,160评论 2 27
  • Redis 初 级 精 讲 ...
    文思li阅读 1,159评论 0 0
  • 1.1 资料 ,最好的入门小册子,可以先于一切文档之前看,免费。 作者Antirez的博客,Antirez维护的R...
    JefferyLcm阅读 17,320评论 1 51
  • 记得李笑来建议:为了避免偏见(选择性输入)害己,要经常记录一些你看到的不同意见,写出反对或者无法理解的理由。 于是...
    长海1994阅读 328评论 1 0

友情链接更多精彩内容