利用Redis统计24小时内的访问量
利用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:
1 2 3 4 5 6 7 8 9 10 11
| try { $redis = new Redis(); $redis->connect('127.0.0.1', 6379); $redis -> select(1); } 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' => '系统错误,请联系管理员')); exit; }
|
接着可以通过$_SERVER['REMOTE_ADDR']
等函数获取 访问者ip,获取访问者IP之后,我们需要在Redis中检查这个键是否存在,如果不存在则需要新建:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| $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获取表内的数据个数:
1 2 3 4 5 6
| if($redis -> llen($redis_key_name) >= $limit_num){ } $redis -> expire($redis_key_name,$limit_time);
|
demo