Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1661771
  • 博文数量: 695
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 4027
  • 用 户 组: 普通用户
  • 注册时间: 2013-11-20 21:22
文章分类

全部博文(695)

文章存档

2018年(18)

2017年(74)

2016年(170)

2015年(102)

2014年(276)

2013年(55)

分类: Python/Ruby

2015-12-04 16:01:38

最近又需要做一个简单的ip访问限制。这一次经别人提醒,学到了另外一种方法去实现。这次是用memcache实现的。

    需求:限制单个ip地址单位时间内的访问次数,比如5分钟内10次。

    实现方法1:python + memcache

    原理: 分析条件就是要知道这个ip在哪段时间内?当前的访问次数是多少?

 

    准备工作是安装memcache和python的客户端

 

    思路:把ip作为key,把一个unix时间戳和这个ip的访问次数用'-'分隔符一起作为value, set到memcache中。 当一个新的ip地址来的时候先set,然后如果这个ip地址不是第一次来的话,就要判断做3个逻辑。

 

第一个:如果这个ip在单位时间内访问次数已经等于或者大于限制的次数的话就返回True表示要限制这个ip地址的访问次数了。

 

第二个:如果这个ip地址在单位时间内访问次数没有超过限制次数,那么就访问次数+1

第三个:如果这个ip地址超过了单位时间内仍然没有超过限制,那么就把当前unix时间刷新到value中,并把访问次数置为1.

 

 

以下是实现代码:

 

 

Python代码  收藏代码
  1. import memcache  
  2.   
  3. def ip_limit(ip):  
  4.     '''''  
  5.     return True if need to limit ip, otherwise return False 
  6.     '''  
  7.     sep = '-'   
  8.     mc = memcache.Client(['127.0.0.1:11211'], debug=0)  
  9.     now = int(time.time())  
  10.     value = mc.get(ip)  
  11.     if not value:  
  12.         #set this ip the first time to access  
  13.         #format is time-count  
  14.         v = '%s%s%s' % (str(now), sep, '1')  
  15.         mc.set(ip, v)  
  16.         return False  
  17.   
  18.     else:  
  19.         #last_access_time and access_times is string  
  20.         value_list = value.split(sep)  
  21.         #now last_access_time and access_times is int  
  22.         last_access_time, access_times = int(value_list[0]), int(value_list[1])  
  23.         if (now - last_access_time) <= config.IP_COLD_TIME and access_times >= config.IP_MAX_ACCESS_TIMES:  
  24.             return True  
  25.   
  26.         elif (now - last_access_time) <= config.IP_COLD_TIME:   
  27.             access_times += 1  
  28.             mc.set(ip, '%s%s%s' % (str(last_access_time), sep, str(access_times)))  
  29.             return False  
  30.   
  31.         else:  
  32.             mc.set(ip, '%s%s%s' % (str(now), sep, '1'))  
  33.             return False  

 

 

代码里面的config是一个config.py文件,用配置的方式配置多长时间(单位:秒)IP_COLD_TIME 和 要限制的访问次数

IP_MAX_ACCESS_TIMES, 方便随时可以修改。

 

 

    实现方法2: 用python+数据库mysql

    具体: 建立一张ip表,表结构很简单:ip_table(ip, varchar 20, access_time int)

 

    查询有没有在单位时间内超过限制次数的逻辑大概如下:

 


Python代码  收藏代码
  1. def limit_ip(ip, now):  
  2.     """  
  3.     return True if need to limit ip,otherwise return False 
  4.     @ip: ip address that is 'xxx.xxx.xxx.xxx' 
  5.     @now: unix time, int 
  6.     """  
  7.     sql = """SELECT COUNT(*) AS times FROM ip_table WHERE ip = %s and access_time > %s and access_time < %s"""  
  8.     access_times = conn.query(sql, (ip, now - config.IP_COLD_TIME, now))[0]["times"]  
  9.     if access_times < config.IP_MAX_ACCESS_TIMES and access_times >= 0:  
  10.         return False  
  11.     return True  

     插入ip就很简单了,直接insert就可以 了。

阅读(867) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~