利用Redis实现统计24小时内的访问量

需求

  我们这里的需求是,记录不同用户在24小时(指定时间)内的访问量,并记录访问日志。如果达到一定的频率则封禁IP

测试环境

Redis 6.2.4
PHP 8.0

开始

  我们先来了解一下Redis,Redis是一个高性能的Key => Value缓存器,由于数据缓存在内存中,所以比Mysql等数据库等响应速度要快几十到上百倍。

  在这个实例中,我们用到的是Redis的Hash类型,通过用户每次访问,在Redis中记录访问者的IP以及对应的时间戳,来达到统计的目的,并且判断该IP访问的历史时间戳是否超过了24小时,如果超过则删除,最终通过llen来获取24小时内的访问次数。

  首先我们通过PHP连接Redis:

    try {
            $redis = new Redis(); 
            $redis->connect('127.0.0.1', 6379);
            $redis -> select(1); //选择DB1
        } catch (Exception $e) {
            header('Content-type:text/json');
            header('Access-Control-Allow-Origin: *');
            header('ERROR: redis -> ' . $e->getMessage());
            echo json_encode(array('code' => 444,'msg' => '系统错误,请联系管理员')); // redis连接失败
            exit; 
        }

   接着可以通过$_SERVER['REMOTE_ADDR']等函数获取 访问者ip,获取访问者IP之后,我们需要在Redis中检查这个键是否存在,如果不存在则需要新建:

 $redis_key_name = 用户IP;
 if($redis -> exists($redis_key_name)){
        while(True) {
            //检查历史访问的时间戳是否过期,过期则删除
            $da = $redis -> lRange($redis_key_name,0,1)[0] ?? '';
            if(time() - (int)$da >= $limit_time){
                $redis -> lrem($redis_key_name,$da,0);
            } else {
                break;
            }
        }
        //写入当前时间戳
        $redis -> rPushx($redis_key_name,time());
        $num = $redis -> llen($redis_key_name);
    } else {
        $redis -> lPush($redis_key_name,time());
        $num = 1;
    }

  之后我们可以直接使用llen获取表内的数据个数:

if($redis -> llen($redis_key_name) >= $limit_num){
        //超过限制数目 -> banip
    }
$redis -> expire($redis_key_name,$limit_time); //这里用来设置键的有效期 ,超过24小时则删除

//同时可以通过error_log()函数记录用户的访问信息

demo

  式例: https://github.com/soxft/Redis-Record

Last modification:July 19th, 2021 at 08:30 pm
If you think my article is useful to you, please feel free to appreciate