简单的窗口限流操作,通过zset来实现
- 步骤
- 1,单个用户uid + 某个行为 作为redis中的key
- 2, 用毫秒时间戳做zset中的key和value
- 3,每次请求过来计算当前时间到往前推算n分钟/秒的请求
- 4,删除zset中关于n分钟前的数据
- 优点
- 缺点
- 2, 如果限制次数非常大,那么会消耗大量的储存空间
- python 代码示例
def record(map):
"记录行为
"
try:
map = {timestamp:timestamp}
rds_client = db_manager.RedisPool.get_connection()
name = "uid_action"
rds_client.zadd(name, **map)
# 删除前两个小时的数据
s_timestamp = int(time.time() * 1000) - 7200000
rds_client.zremrangebyscore(name, 0, float(s_timestamp))
except:
logger.error(traceback.format_exc())
logger.error(not_feiyi_bk_map)
def is_req_limit():
"""如果一分钟请求超过十次,返回true,对此请求进行拦截"""
rds_client = db_manager.RedisPool.get_connection()
name = "uid_action"
# 计算一分钟内请求次数是否符合规则
s_timestamp = int(time.time() * 1000) - 3600000 / 60
e_timestamp = int(time.time() * 1000)
count = rds_client.zcount(name, s_timestamp, e_timestamp)
if count > 10:
return True
return False
redis 漏斗限流–》Redis-Cell
cl.throttle key 15 30 60 1
key:行为key
15: 漏斗容量
30 60:这是漏水速率 30 op / 60 seconds
1: 可选参数
含义: 这个key的行为,一开始可以不限制的执行15次,满了十五次以后需要等漏斗开始执行。比如然后就是没错两秒可以执行一次
> cl.throttle laoqian:reply 15 30 60
1) (integer) 0 # 0 表示允许, 1 表示拒绝
2) (integer) 15 # 漏斗容量 capacity
3) (integer) 14 # 漏斗剩余空间 left_quota
4) (integer) -1 # 如果拒绝了,需要多长时间后再试(漏斗有空间了,单位秒)
5) (integer) 2 # 多长时间后,漏斗完全空出来(left_quota==capacity,单位秒)