第一种是直接传入用户id和接口名称,对其进行每分钟30次的限制
import redis
r = redis.Redis(host='localhost', port=6379, db=0)
def check_rate_limit(user_id, interface):
current_time = int(time.time())
minute = current_time // 60
# 获取当前分钟内用户的调用次数
call_count = r.get(f'user:{user_id}:interface:{interface}:minute:{minute}')
print(call_count)
if call_count is None:
call_count = 0
else:
call_count = int(call_count)
# 每分钟限定次数 30 次
if call_count < 30:
# 调用次数未超过限制,增加调用次数并返回 True 表示允许调用
r.incr(f'user:{user_id}:interface:{interface}:minute:{minute}')
return True
else:
# 调用次数超过限制,返回 False 表示拒绝调用
return False
第二种是Django里面的装饰器,对需要限制的接口进行处理
import redis
import time
from functools import wraps
from django.http import JsonResponse
r = redis.Redis(host='localhost', port=6379, db=0)
def rate_limit_decorator(interface):
def decorator(func):
@wraps(func)
def wrapper(request, *args, **kwargs):
user_id = request.user.id # 假设您可以从请求中获取用户 ID
current_time = int(time.time())
minute = current_time // 60
call_count = r.get(f'user:{user_id}:interface:{interface}:minute:{minute}')
if call_count is None:
call_count = 0
else:
call_count = int(call_count)
if call_count < 3:
r.incr(f'user:{user_id}:interface:{interface}:minute:{minute}')
return func(request, *args, **kwargs)
else:
return JsonResponse({'message': '调用频率超过限制'}, status=429) # 429 表示请求过多
return wrapper
return decorator
# 示例用法
@rate_limit_decorator('get_name')
def get_name(request):
# 您的方法实现
return JsonResponse({'name': 'John Doe'})