DRF的限流组件(源码分析)
DRF限流组件(源码分析)
限流,限制用户访问频率,例如:用户1分钟最多访问100次 或者 短信验证码一天每天可以发送50次, 防止盗刷。
- 对于匿名用户,使用用户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_%(scope)s_%(ident)s'
# 设置其他访问评率, 例如: 一分钟允许访问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中具体分析

- allow_request()在自定义的类里面没定义, 所以我们到父类SimpleRateThrottle执行allow_request()方法

DRF的限流组件(源码分析)的更多相关文章
- alibaba sentinel限流组件 源码分析
如何使用? maven引入: <dependency> <groupId>com.alibaba.csp</groupId> <artifactId>s ...
- 面试官:来谈谈限流-RateLimiter源码分析
RateLimiter有两个实现类:SmoothBursty和SmoothWarmingUp,其都是令牌桶算法的变种实现,区别在于SmoothBursty加令牌的速度是恒定的,而SmoothWarmi ...
- Django框架之drf:8、断点调试,权限、认证、频率组件源码分析,基于APIView编写分页,异常处理
Django框架之drf 一.断点调式使用 指,在我们编写代码的时候,程序运行出现报错是无可避免的,当程序 出现报错时,我们需要找到出现报错的代码进行修改,如果时简短的代码很容易就可以找到报错位置 ...
- Django-restframework 源码之认证组件源码分析
Django-restframework 源码之认证组件源码分析 一 前言 之前在 Django-restframework 的流程分析博客中,把最重要的关于认证.权限和频率的方法找到了.该方法是 A ...
- element-ui 组件源码分析整理笔记目录
element-ui button组件 radio组件源码分析整理笔记(一) element-ui switch组件源码分析整理笔记(二) element-ui inputNumber.Card .B ...
- ceph-csi组件源码分析(1)-组件介绍与部署yaml分析
更多ceph-csi其他源码分析,请查看下面这篇博文:kubernetes ceph-csi分析目录导航 ceph-csi组件源码分析(1)-组件介绍与部署yaml分析 基于tag v3.0.0 ht ...
- 开源MyBatisGenerator组件源码分析
开源MyBatisGenerator组件源码分析 看源码前,先了解Generator能做什么? MyBatisGenerator是用来生成mybatis的Mapper接口和xml文件的工具,提供多种启 ...
- element-ui button组件 radio组件源码分析整理笔记(一)
Button组件 button.vue <template> <button class="el-button" @click="handleClick ...
- element-ui MessageBox组件源码分析整理笔记(十二)
MessageBox组件源码,有添加部分注释 main.vue <template> <transition name="msgbox-fade"> < ...
- Django REST framework —— 权限组件源码分析
在上一篇文章中我们已经分析了认证组件源码,我们再来看看权限组件的源码,权限组件相对容易,因为只需要返回True 和False即可 代码 class ShoppingCarView(ViewSetMix ...
随机推荐
- rust 条件编译 Debug Release
#[cfg(debug_assertions)] macro_rules! debug { () => (std::println!()); ($($arg:tt)*) => ({ pri ...
- 【内存管理】CMA内存分配器(Contiguous Memory Allocator)
什么是CMA 参考这两篇博文,写得很好: http://www.wowotech.net/memory_management/cma.html https://www.cnblogs.com/Loye ...
- idea初学
IDEA 什么是IDE IDEA官网 idea中文设置:打开右上角设置选择设置,选择Plugins ,搜索Chinese,安装插件后重启即可 IDEA基础语法 注释 编写代码量多时,项目结构复杂,需要 ...
- CH573 CH582 CH579蓝牙从机(peripheral)例程讲解三(蓝牙服务修改)
修改服务需要对蓝牙比较熟悉的工程师去完成,否则在例程功能满足自己需求时,不建议修改,很容易改错,下面就简单介绍下如何在别的char添加一个nofify属性. step1: 给Simple Profil ...
- 第三章 excel的表合并
本章内容比较简略,基于行或列进行统计运算 具体操作为:选中某一空白单元格,单击数据--数据工具--合并计算(依据需求选择数据与计算方式)
- 下载Vmware 15版本的虚拟机(转载)
参考网址: https://blog.csdn.net/ITloser_cartridge/article/details/91347452 不登录VMware的下载方法: https://blog. ...
- GDB使用详解
来源:GDB使用详解 - 知乎 (zhihu.com) 1. 概述 GDB 全称"GNU symbolic debugger",从名称上不难看出,它诞生于 GNU 计划(同时诞 ...
- 关于Go语言的底层,你想知道的都在这里!
目录 1. GoLang语言 1.1 Slice 1.2 Map 1.3 Channel 1.4 Goroutine 1.5 GMP调度 1.6 垃圾回收机制 1.7 其他知识点 2. Web框架Gi ...
- 三天吃透RabbitMQ面试八股文
本文已经收录到Github仓库,该仓库包含计算机基础.Java基础.多线程.JVM.数据库.Redis.Spring.Mybatis.SpringMVC.SpringBoot.分布式.微服务.设计模式 ...
- PO、VO、DAO、BO、DTO、POJO 之间的区别
PO(Persistant Object),持久对象 这个对象是与数据库中的表相映射的Java对象. VO(Value Object),值对象 通常用于业务层之间的数据传递,和PO一样也是仅仅包含数据 ...