今天在网站上无意浏览到小杰的网站,发现他的API接口网站做了访问频率限制。
感觉这个挺不错的,1.可以降低自己网站的的运行压力,2.可以防止别人过分调用。
然后就想自己也实现一个。但又不知道他的实现方法是什么,就自己想了一个实现方法。
分析:
1.访问肯定要做判断的,想到网络判断第一想到的就是IP。
2.访问次数肯定要记录一下才行啊!而且还要个记录时间。不然不好判断啊。
然后就能想到刚好就有这么个数据库完全可以实现我的需求——Redis数据库。
之后就是写代码:
<?php //Redis的key可以有2.5亿个,所以不用担心key占满 //Redis读的速度是110000次/s,写的速度是81000次/s 。 //速度和存储完全可以达到我的需求。 $redis = new Redis(); $redis->connect('127.0.0.1', 6379); //连接Redis $redis->auth('123456'); //密码验证(没密码可以注释掉本部分) $key = "ip";//要记录的key,key可以用IP......来达到限制。 $limit = 3;//限制次数 $k_time = 1;//秒 $check = $redis->exists($key); if($check){//检查是否存在 $redis->incr($key); //键值递增 $count = $redis->get($key); if($count > $limit){ exit('刷新频率达到'.$k_time.'秒'.$limit.'次限制'); } }else{ $redis->incr($key);//初始化key的value为0 $redis->expire($key,$k_time);//限制时间为$k_time秒 } $count = $redis->get($key); echo '刷新成功,当前次数为'.$count.'次'; ?>之后又简单的封装了一下:
<?php //获取真实IP function getIP() { global $ip; if (getenv("HTTP_CLIENT_IP")) $ip = getenv("HTTP_CLIENT_IP"); else if(getenv("HTTP_X_FORWARDED_FOR")) $ip = getenv("HTTP_X_FORWARDED_FOR"); else if(getenv("REMOTE_ADDR")) $ip = getenv("REMOTE_ADDR"); else $ip = "Unknow"; return $ip; } /** *刷新频率验证 *$redis:操作的Redis *$key :记录值 *$limit:访问次数 *$k_time:key记录时间 */ function Refresh($redis,$key,$limit,$k_time){ $check = $redis->exists($key); if($check){//检查是否存在 $redis->incr($key); //键值递增 $count = $redis->get($key); if($count > $limit){ return false; } }else{ $redis->incr($key);//初始化key的value为0 $redis->expire($key,$k_time);//限制时间为$k_time秒 } return true; } $redis = new Redis(); //创建Redis $redis->connect('127.0.0.1', 6379); //连接Redis $redis->auth('123465'); //密码验证(没密码可以注释掉本部分) if(Refresh($redis,getIP(),3,1)){//同一IP地址1秒内只允许访问3次。 echo '</br>可以正常访问'; }else{ echo '</br>访问次数过高'; } ?>虽然功能实现了,但我却没能应用到我的API网站上,我的API网站是用虚拟空间搭建的所以没有Redis数据库,想到过通过外网连接我服务器的Redis数据库但我服务器带宽太低了,所以怕影响API接口的调用速度就没能添加。
发表评论