栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > PHP

详解php基于redis的list型数据结构实现ip限流操作

PHP 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

推荐:《PHP视频教程》

在日常的业务功能开发中,如果要 限制任意一个ip在连续的某一段时间内,只能访问某个接口一定的次数,需要如何实现呢?
这种功能需求通常是用来应对防止脚本恶意刷接口的情况,目前网上已经有很多比较完善的限流方案。对于一般的站点来讲,可以借助redis的链表型数据结构来实现ip限流功能。
举个例子——
假如我们需要实现,对于接口A,限制任意IP在每一段连续的5秒内,最多允许3次访问,超过3次则返回报错。

file

对于上图来讲,在08秒的时候,最近的5秒内已经发起了4次请求,已经达到最大次数限制,所以此时访问会受限。
采用PHP来实现的话,具体的逻辑代码如下——

public function checkLimit($key, $expire, $limit){
    $length = $this->refreshList($key, $expire);
    if ($length < $limit) {
 // 未到达访问限制,将当前时间戳推入到list的最后边,同时把整个key的过期时间重新更新
 $this->rPush($key, time());
 $this->expire($key, intval($limit));
 return true;
    }
    return false;}public function refreshList ($key, $expire)   
 {
 if ($this->has($key)) {
     do { // 对于已存在数据的list,要先从前往后把已经过期的数据弹出
  $oldest_value = $this->lPop($key);
     } while ($oldest_value && time() - $oldest_value > $expire);
     // 把最后弹出的数据重新塞回list的最前边
     $oldest_value && $this->lPush($key, $oldest_value);
     return $this->lLen($key);
 }
 return 0;}

其中用到的lPop,lPush,lLen,rPush等方法,都是封装了redis拓展之后,操作链表型数据结构的一些方法,参数跟返回值都与原生方法保持一致。
其实后来网上查了之后才知道,redis处理这种场景,更多的是直接用zset这种有序集来实现,逻辑也是基本一致,就是存当前时间戳,然后用滑动窗口的算法思想,判断当前窗口内的值长度是否已经超过限制。

以上就是详解php基于redis的list型数据结构实现ip限流操作的详细内容,更多请关注考高分网其它相关文章!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/262618.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号