DRF的限流组件(源码分析)

科技资讯 投稿 5500 0 评论

DRF的限流组件(源码分析)

DRF限流组件(源码分析

    对于匿名用户,使用用户IP作为唯一标识。
  • 对于登录用户,使用用户ID或名称作为唯一标识。
缓存={
	用户标识:[12:33,12:32,12:31,12:30,12,]    1小时/5次   12:34   11:34
{

1. 配置缓存

# settings.py
CACHES = {
    "default": {
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": "redis://127.0.0.1:6379",
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
            "PASSWORD": "qwe123",
        }
    }
}

2. 自定义限流类

# -*- encoding:utf-8 -*-
# @time: 2023/4/21 15:41
# @author: ifeng
from django.core.cache import cache as default_cache
from rest_framework import exceptions
from rest_framework import status
from rest_framework.throttling import SimpleRateThrottle


class ThrottledException(exceptions.APIException:
    status_code = status.HTTP_429_TOO_MANY_REQUESTS
    default_code = 'throttled'


class MyRateThrottle(SimpleRateThrottle:
    cache = default_cache  # 访问记录存放在django的缓存中(需设置缓存
    scope = 'user'  # 构造缓存中的key
    cache_format = 'throttle_%(scopes_%(idents'

    # 设置其他访问评率, 例如: 一分钟允许访问10次
    # 其他: 's': 'sec', 'm': 'min', 'h': 'hour', 'd': 'day'
    THROTTLE_RATES = {'user': '10/m'}

    def get_cache_key(self, request, view:
        if request.user:
            ident = request.user.id
        else:
            ident = self.get_ident(request  # 获取请求用户IP(request中找请求头

        # throttle_u # throttle_user_11.11.11.11ser_2

        return self.cache_format % {'scope': self.scope, 'ident': ident}

    def throttle_failure(self:
        wait = self.wait(
        detail = {
            'code': 1005,
            'data': '访问频率限制',
            'detail': '需要等待 %s s才能访问' % (int(wait
        }
        raise ThrottledException(detail

3. 使用限流类

    局部配置(views
class UserView(APIView:
    throttle_classes = [MyRateThrottle, ]  # 限流
    全局配置(settings
REST_FRAMEWORK = {
    # 限流
    "DEFAULT_THROTTLE_CLASSES": ["app01.throttle.MyRateThrottle", ],
    "DEFAULT_THROTTLE_RATES": {
        "user": "10/m",
        # "xx":"100/h"
    }
}

4. 多个限流类

本质,每个限流的类中都有一个 allow_request 方法,此方法内部可以有三种情况:

    返回True,表示当前限流类允许访问,继续执行后续的限流类。
  • 返回False,表示当前限流类不允许访问,继续执行后续的限流类。所有的限流类执行完毕后,读取所有不允许的限流,并计算还需等待的时间。
  • 抛出异常,表示当前限流类不允许访问,后续限流类不再执行。

5. 源码分析

    这是限流大体的执行逻辑, 后面将对allow_reqeust中具体分析
  1. allow_request(在自定义的类里面没定义, 所以我们到父类SimpleRateThrottle执行allow_request(方法

编程笔记 » DRF的限流组件(源码分析)

赞同 (33) or 分享 (0)
游客 发表我的评论   换个身份
取消评论

表情
(0)个小伙伴在吐槽