1. 限流组件源码分析

注意:以下源码为方便理解已进行简化,只保留了与限流组件相关的代码。注释前的数字代表执行顺序。



SimpleRateThrottle类的源码解析:

2. 实践:编写一个限流类

from rest_framework.throttling import SimpleRateThrottle
from django.core.cache import cache as default_cache class IpThrottle(SimpleRateThrottle):
scope = "ip" # 节流类的名称
# THROTTLE_RATES = {"x1": "5/m"} 类中未定义THROTTLE_RATES则去settings中获取
cache = default_cache # 节流类指定写入的缓存 def get_cache_key(self, request, view):
ident = self.get_ident(request) # 获取请求用户IP(去request中找请求头)
return self.cache_format % {'scope': self.scope, 'ident': ident} class UserThrottle(SimpleRateThrottle):
scope = "user" # 节流类的名称
# THROTTLE_RATES = {"x1": "5/m"} 类中未定义THROTTLE_RATES则去settings中获取
cache = default_cache # 节流类指定写入的缓存 def get_cache_key(self, request, view):
ident = request.user.pk # 用户ID
return self.cache_format % {'scope': self.scope, 'ident': ident}

3. 源码改编

  • 重写限流的时长规则:原本只支持 1分钟x次,重写后支持 x分钟x次:
def parse_rate(self, rate):
'''重写获取时长的parse_rate方法,原本只能写1/m或2/m,现在支持:1/5m, 3/10m的格式'''
if rate is None:
return (None, None)
num, period = rate.split('/') # "1/5m"
num_requests = int(num)
duration = {'s': 1, 'm': 60, 'h': 3600, 'd': 86400}[period[-1]]
count = int(period[0:-1])
return (num_requests, duration * count)
  • 请求操作失败时,不计入限流次数
# 思路:在视图的操作成功后再进行计入操作(throttle_success)
# 限流类中: 重写throttle_success操作,并把计次的操作提取出来,自定义一个函数,在视图操作成功后才调用该函数进行计次
class MyThrottle(SimpleRateThrottle): def throttle_success(self):
# self.history.insert(0, self.now)
# self.cache.set(self.key, self.history, self.duration)
return True def done(self):
""" 视图函数执行成功后,再调用throttle_success里的方法"""
self.history.insert(0, self.now)
self.cache.set(self.key, self.history, self.duration) # 视图类中:
class MyView(APIView):
def post(request):
"""中间代码省略"""
# 成功操作后才记录一次限流
for throttle in self.get_throttles():
throttle.done()
  • 自定义限流类的报错信息
# 在限流类中:
# 自定义抛出报错的异常类
class ThrottledException(exceptions.APIException):
status_code = status.HTTP_429_TOO_MANY_REQUESTS
default_code = 'throttled' #重写throttle_failure方法,自定义报错信息并直接抛出异常;
def throttle_failure(self):
wait = self.wait()
detail = {
"code": return_code.TOO_MANY_REQUESTS,
"data": "访问频率限制",
'detail': "需等待{}秒后才能访问".format(int(wait))
}
raise ThrottledException(detail)

DRF-Throttle组件源码分析及改编源码的更多相关文章

  1. drf的基本使用、APIView源码分析和CBV源码拓展

    cbv源码拓展 扩展,如果我在Book视图类中重写dispatch方法 -可以实现,在get,post方法执行之前或者之后执行代码,完成类似装饰器的效果 def dispatch(self, requ ...

  2. NIO 源码分析(05) Channel 源码分析

    目录 一.Channel 类图 二.begin 和 close 是什么 2.1 AbstractInterruptibleChannel 中的 begin 和 close 2.2 Selector 中 ...

  3. NIO 源码分析(02-2) BIO 源码分析 Socket

    目录 一.BIO 最简使用姿势 二.connect 方法 2.1 Socket.connect 方法 2.2 AbstractPlainSocketImpl.connect 方法 2.3 DualSt ...

  4. NIO 源码分析(02-1) BIO 源码分析

    目录 一.BIO 最简使用姿势 二.ServerSocket 源码分析 2.1 相关类图 2.2 主要属性 2.3 构造函数 2.4 bind 方法 2.5 accept 方法 2.6 总结 NIO ...

  5. [源码分析] 从实例和源码入手看 Flink 之广播 Broadcast

    [源码分析] 从实例和源码入手看 Flink 之广播 Broadcast 0x00 摘要 本文将通过源码分析和实例讲解,带领大家熟悉Flink的广播变量机制. 0x01 业务需求 1. 场景需求 对黑 ...

  6. Spring Ioc源码分析系列--Ioc源码入口分析

    Spring Ioc源码分析系列--Ioc源码入口分析 本系列文章代码基于Spring Framework 5.2.x 前言 上一篇文章Spring Ioc源码分析系列--Ioc的基础知识准备介绍了I ...

  7. k8s client-go源码分析 informer源码分析(3)-Reflector源码分析

    k8s client-go源码分析 informer源码分析(3)-Reflector源码分析 1.Reflector概述 Reflector从kube-apiserver中list&watc ...

  8. 5.2 spring5源码--spring AOP源码分析三---切面源码分析

    一. AOP切面源码分析 源码分析分为三部分 1. 解析切面 2. 创建动态代理 3. 调用 源码的入口 源码分析的入口, 从注解开始: 组件的入口是一个注解, 比如启用AOP的注解@EnableAs ...

  9. jQuery1.11源码分析(1)-----Sizzle源码概览[原创]

    最近在啃jQuery1.11源码,上来就遇到Sizzle这个jQuery的大核心,虽然已经清楚了Sizzle的用途,先绕过去也没事,但明知山有虎偏向虎山行才是我们要做的. 本文面向的阅读对象:正在学习 ...

  10. 【MyBatis源码分析】select源码分析及小结

    示例代码 之前的文章说过,对于MyBatis来说insert.update.delete是一组的,因为对于MyBatis来说它们都是update:select是一组的,因为对于MyBatis来说它就是 ...

随机推荐

  1. hibernate validation,spring validation自定义参数校验

    1.背景 在实际开发中,我们除了会使用常用的参数判断,如字符串不为空,最大值,最小值等 我们还可以自定义参数校验规则 2.实际生产问题 实际生产中同步订单的时候, 假设我们要求订单状态值只能是 -1, ...

  2. 调用lcd屏输出德国国旗

    /************************************************* * * file name:color.c * author :momolyl@126.com * ...

  3. PowerShell快速修改多个文件的名称

      本文介绍基于PowerShell语言,对文件夹中全部文件的名称加以批量替换.修改的方法.   在之前的文章中,我们介绍了基于Python语言,批量修改大量文件的名称的方法.当时我们修改文件名的需求 ...

  4. idea关闭窗口快捷键

    File->settings->keymap->main menu->window->editor tabs->close 根据自己的使用习惯将想要关闭的标签设置快 ...

  5. python配置pip镜像

    Python配置pip的镜像 国内的网络通过pip下载软件包只有不到10k的下载速度.不仅下载的慢,还容易引发超时错误,导致下载失败.而将给pip配置国内的镜像源可以完美的解决这个问题.本文讲解了pi ...

  6. Mac 打开软件提示‘“xxx”已损坏,无法打开。您应该将它移到废纸篓。’解决方法

    产生错误的原因是软件没有签名.使用下面的命令给软件签名就好了. sudo xattr -rd com.apple.quarantine /Applications/xxx.app

  7. Windows 服务管理

    创建服务 New-Service -Name NAME -BinaryPathName COMMAND -StartupType Automatic -Description DESCRIPTION ...

  8. 【测试平台开发】——04Flask后端api开发实战(一)

    一.测试平台开发模式 要开发一套平台有两种开发模式,一个[大而全],一个[小而简]. 说道[大而全]想到目前大型项目都使用的语言[JAVA],[小而简]想到的是[Python]语言. 重武器(大而全) ...

  9. 【YashanDB知识库】filter or改写问题

    问题现象 当filter中出现or的时候,会导致filter无法走索引或者走hash join,就需要进行改写,例如: create table test_tab1(col1 int, col2 in ...

  10. C++ : 如何用C语言实现C++的虚函数机制?

    前言 在 googletest的源码中,看到gtest-matchers.h 中实现的MatcherBase 类自定义了一个 VTable,这种设计实现了一种类似于C++虚函数的机制.C++中的虚函数 ...