最近又需要做一个简单的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.
以下是实现代码:
-
import memcache
-
-
def ip_limit(ip):
-
''
-
-
-
sep = '-'
-
mc = memcache.Client(['127.0.0.1:11211'], debug=0)
-
now = int(time.time())
-
value = mc.get(ip)
-
if not value:
-
-
-
v = '%s%s%s' % (str(now), sep, '1')
-
mc.set(ip, v)
-
return False
-
-
else:
-
-
value_list = value.split(sep)
-
-
last_access_time, access_times = int(value_list[0]), int(value_list[1])
-
if (now - last_access_time) <= config.IP_COLD_TIME and access_times >= config.IP_MAX_ACCESS_TIMES:
-
return True
-
-
elif (now - last_access_time) <= config.IP_COLD_TIME:
-
access_times += 1
-
mc.set(ip, '%s%s%s' % (str(last_access_time), sep, str(access_times)))
-
return False
-
-
else:
-
mc.set(ip, '%s%s%s' % (str(now), sep, '1'))
-
return False
代码里面的config是一个config.py文件,用配置的方式配置多长时间(单位:秒)IP_COLD_TIME 和 要限制的访问次数
IP_MAX_ACCESS_TIMES, 方便随时可以修改。
实现方法2: 用python+数据库mysql
具体: 建立一张ip表,表结构很简单:ip_table(ip, varchar 20, access_time int)
查询有没有在单位时间内超过限制次数的逻辑大概如下:
-
def limit_ip(ip, now):
-
-
-
-
-
-
sql =
-
access_times = conn.query(sql, (ip, now - config.IP_COLD_TIME, now))[0]["times"]
-
if access_times < config.IP_MAX_ACCESS_TIMES and access_times >= 0:
-
return False
-
return True
插入ip就很简单了,直接insert就可以 了。
阅读(872) | 评论(0) | 转发(0) |