DRF-源码解析-4-限流的流程:drf的限流源码,drf流量控制流程,drf如何流量控制

请添加图片描述

流量控制的逻辑:

1、设置一个唯一标识,作为cache的key

2、请求访问时,构造唯一标识,从ceche中获取[时间1,时间2,时间3,…]

3、根据设置流量控制规则,如:5/m (一分钟最多访问5次),判断该唯一标识记录到cache中的访问时间的次数,是否满足请求的条件

4、不满足,就抛出异常,前端收到请求过快的响应。满足访问,就直接访问。

一、代码的准备

视图:

class TestAPIView(APIView):authentication_classes=[MyJWTAuthentication]permission_classes = [AdminPermission,]def get(self,request)return Respponse({'code':200,'msg':'测试通过'})

路由:

path('test/',views.TestAPIView.as_view())

请求方式:GET

流量控制类:

from rest_framework.throttling import SimpleRateThrottle#对请求源的IP进行限制
class IPThrottle(SimpleRateThrottle):# 在settings中配置频率时使用到的关键字,有scope来指定scope = 'IP'def get_cache_key(self, request, view):return f'{self.scope}-{self.get_ident(request)}-throttle'# 这里return什么,就以什么作为限制,这里限制ip,直接return ip就可以return request.META.get('REMOTE_ADDR')# 可以在这里设置访问频率# def get_rate(self):#     return '3/m'

二、具体的流程

1、TestAPIView的as_view方法,当前实例对象没有,找父类的APIView的as_view

@classmethod
def as_view(cls, **initkwargs):#1、调用APIView父类的as_view方法view = super().as_view(**initkwargs)view.cls = clsview.initkwargs = initkwargs#2、去除掉csrf校验return csrf_exempt(view)

2、APIView的as_view是调用父类View的as_view方法

@classonlymethod
def as_view(cls, **initkwargs):def view(request, *args, **kwargs):self = cls(**initkwargs)self.setup(request, *args, **kwargs)if not hasattr(self, 'request'):raise AttributeError("%s instance has no 'request' attribute. Did you override ""setup() and forget to call super()?" % cls.__name__)return self.dispatch(request, *args, **kwargs)view.view_class = clsview.view_initkwargs = initkwargsreturn view#返回的是闭包view,
#view的功能就是self.dispatch()方法

3、as_view主要返回闭包,关于self.dispatch()方法

4、self是TestAPIView , 没有dispatch方法,调用父类APIView的dispatch方法

#简化后的源码

    def dispatch(self, request, *args, **kwargs):#处理url中的参数self.args = argsself.kwargs = kwargs#构建drf的request对象request = self.initialize_request(request, *args, **kwargs)self.request = requestself.headers = self.default_response_headers  # deprecate?try:#认证、权限、限流的执行self.initial(request, *args, **kwargs)#通过反射来执行TestAPIView中的get、post等方法if request.method.lower() in self.http_method_names:handler = getattr(self, request.method.lower(),self.http_method_not_allowed)else:handler = self.http_method_not_allowed#视图函数执行结果response = handler(request, *args, **kwargs)except Exception as exc:response = self.handle_exception(exc)self.response = self.finalize_response(request, response, *args, **kwargs)return self.response

5、self.initial(request,),TestAPIView中没有,找APIView的initial方法,

    def initial(self, request, *args, **kwargs):#认证、权限、限流self.perform_authentication(request)self.check_permissions(request)self.check_throttles(request)

6、TestAPIView没有check_throttles,调用APIView的check_throttles

    def check_throttles(self, request):throttle_durations = []for throttle in self.get_throttles():if not throttle.allow_request(request, self):throttle_durations.append(throttle.wait())if throttle_durations:durations = [duration for duration in throttle_durationsif duration is not None]duration = max(durations, default=None)self.throttled(request, duration)
  • ​ self.get_throttles(),TestAPIView没有,调用父类APIView的get_throttles()

    •     def get_throttles(self):return [throttle() for throttle in self.throttle_classes]
      
  • 具体流量控制了流程

    • 获取到配置的[限流对象1,限流对象2,…]
    • 执行限流对象.allow_request(request, self) 方法

7、SimpleRateThrottle的allow_request方法

class SimpleRateThrottle(BaseThrottle):def __init__(self):#获取限流的规则,如5/m , 没有就请求get_rate方法if not getattr(self, 'rate', None):self.rate = self.get_rate()#解析限制规则5/m, 允许访问的次数,允许的时间(秒)self.num_requests, self.duration = self.parse_rate(self.rate)def allow_request(self, request, view):if self.rate is None:return True#获取唯一标识,cache的keyself.key = self.get_cache_key(request, view)if self.key is None:return True#获取历史访问的列表[时间点1,时间点2]self.history = self.cache.get(self.key, [])self.now = self.timer()#把历史列表中,超过1分钟的时间点移除(5/m)while self.history and self.history[-1] <= self.now - self.duration:self.history.pop()#如果1分钟内访问的历史次数,大于等于规则5/m中的5,就是访问失败,抛出异常if len(self.history) >= self.num_requests:return self.throttle_failure()#否则访问超过return self.throttle_success()
  • 1、实例化对象时,就解析限流规则,如5/m
  • 2、执行allow_request方法时
    • 判断符合要求的历史访问记录数是否大于等于5
      • 符合:return True
      • 不符合:return False

8、回到APIView.check_throttles()

    def check_throttles(self, request):#记录要等待多少时间,才能请求throttle_durations = []for throttle in self.get_throttles():#如果限流类返回False,就把要等待时间放到throttle_durations列表中if not throttle.allow_request(request, self):throttle_durations.append(throttle.wait())if throttle_durations:durations = [duration for duration in throttle_durationsif duration is not None]#取要等待的最长时间duration = max(durations, default=None)self.throttled(request, duration)

9、限流类.wait() 方法

    def wait(self):if self.history:remaining_duration = self.duration - (self.now - self.history[-1])else:remaining_duration = self.durationavailable_requests = self.num_requests - len(self.history) + 1if available_requests <= 0:return None#当前时间-最早一次符合的请求时间:还需要等待的时间return remaining_duration / float(available_requests)

10、回到APIView.dispatch方法

    def dispatch(self, request, *args, **kwargs):self.args = argsself.kwargs = kwargsrequest = self.initialize_request(request, *args, **kwargs)self.request = requestself.headers = self.default_response_headers  # deprecate?try:#认证、权限、限流self.initial(request, *args, **kwargs)#反射TestAPIView,获取get方法,执行get方法,if request.method.lower() in self.http_method_names:handler = getattr(self, request.method.lower(),self.http_method_not_allowed)else:handler = self.http_method_not_allowedresponse = handler(request, *args, **kwargs)except Exception as exc:response = self.handle_exception(exc)self.response = self.finalize_response(request, response, *args, **kwargs)return self.response
  • 通过反射,拿到TestAPIView中对应的视图函数,执行完成,拿到函数执行结果。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/605523.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于ssm的常见小儿疾病中医护理系统的设计+jsp论文

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本小儿疾病中医护理系统就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大的数据…

湖南大学-计算机网路-2023期末考试【部分原题回忆】

前言 计算机网络第一门考&#xff0c;而且没考好&#xff0c;回忆起来的原题不多。 这门学科学的最认真&#xff0c;复习的最久&#xff0c;考的最差。 教材使用这本书&#xff1a; 简答题&#xff08;6*530分&#xff09; MTU和MSS分别是什么&#xff0c;联系是什么&#x…

如何衡量一个排序算法的性能

这是八股文的知识&#xff0c;但是中国人又个好的习惯&#xff0c;当别人给你一块好吃的面包时&#xff0c;你总想知道这个面包是怎么做的&#xff0c;对于目前的IT行业来说&#xff0c;不管这个做法你是被动的学习还是主动的探索&#xff0c;你都要知道&#xff0c;也必须要知…

如何解决vscode中文路径的问题

首先我们进入设备 搜索“区域”&#xff0c;选择“区域设置” 点击管理语言设置 点击更改系统区域设置&#xff0c;勾选“Beta 版: 使用 Unicode UTF-8 提供全球语言支持(U)”&#xff0c;电脑会叫你重启&#xff0c;你重启就行了

Node.js(四)-express

1. 初识express 1.1 express简介 1.1.1 什么是express 官方&#xff1a;Express是基于Node.js平台&#xff0c;快速、开放、极简的web开发框架。 通俗&#xff1a;Express的作用和Node.js内置的http模块类似&#xff0c;是专门用来创建web服务器的。 express的本质&#xff1…

代码随想录刷题第四十二天| 01背包问题,你该了解这些! ● 01背包问题,你该了解这些! 滚动数组 ● 416. 分割等和子集

代码随想录刷题第四十二天 今天是0-1背包问题&#xff0c;掌握了套路就不难了~~~ 0-1背包问题理论基础&#xff08;二维数组篇&#xff09;卡码网第46题 题目思路&#xff1a; 代码实现&#xff1a; input_line input() # 读取一行输入 mn input_line.split() m, n int…

静态关键字:static

static的作用 static是静态的意思&#xff0c;可以修饰成员变量和成员方法。 static修饰成员变量表示该成员变量只在内存中只存储一份&#xff0c;可以被共享访问、修改。 成员变量 分为2类 静态成员变量&#xff08;有static修饰&#xff0c;属于类&#xff0c;内存中加载…

通用web自动扩缩容_智能运维引擎CudgX

一、概述 CudgX是星汉未来自主研发的面向云原生时代的智能运维引擎&#xff0c;支持根据 MetricQPS 分段耗时指标进行自动扩缩容。 通过各类服务的多维度、大规模的日志数据采集以及机器学习训练分析&#xff0c;对服务进行数字化、指标化度量&#xff0c;并基于部署的…

【Java】设计模式之顺序控制

实际开发中&#xff0c;有时候一些场景需求让多个线程按照固定的顺序依次执行。这个时候就会使用这种模式。 这种模式说白了&#xff0c;就是给线程设定不同的条件&#xff0c;不符合条件的话&#xff0c;就算线程拿到锁也会释放锁进入等待&#xff1b;符合条件才让线程拿到锁…

重生奇迹mu中的智力妹妹都能召唤出哪些宠物呢?

身为重生奇迹mu中的智力妹妹&#xff0c;其实是女性玩家最爱的一种职业&#xff0c;因为她是一种辅助职业&#xff0c;不需要直接参与到战役之中&#xff0c;只需躲藏在队友身后&#xff0c;提供各种BUFF的支援&#xff0c;就能充分发挥其作用&#xff0c;而且身为团队中的唯一…

Redis Geo:掌握地理空间数据的艺术

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 Redis Geo&#xff1a;掌握地理空间数据的艺术 前言Redis Geo基本概念Geo模块的目的工作原理地理坐标系统 GEO的分值1. 经纬度范围2. 二分编码3. Base32编码4. 精度为什么使用Geohash&#xff1f; GEO…

Axure RP Extension For Chrome 插件安装

1. 下载好 AXURE RP EXTENSION For Chrome 插件之后解压成文件夹 2. 打开浏览器&#xff0c;找到设置--更多工具--扩展程序--加载已加压的扩展程序&#xff0c;选择解压好的文件夹 3. 点击详细信息&#xff0c;打开访问网址权限

I.MX6ULL_Linux_驱动篇(52)linux CAN驱动

CAN 是目前应用非常广泛的现场总线之一&#xff0c;主要应用于汽车电子和工业领域&#xff0c;尤其是汽车领域&#xff0c;汽车上大量的传感器与模块都是通过 CAN 总线连接起来的。 CAN 总线目前是自动化领域发展的热点技术之一&#xff0c;由于其高可靠性&#xff0c; CAN 总线…

【性能测试】JMeter分布式测试及其详细步骤

性能测试概要 性能测试是软件测试中的一种&#xff0c;它可以衡量系统的稳定性、扩展性、可靠性、速度和资源使用。它可以发现性能瓶颈&#xff0c;确保能满足业务需求。很多系统都需要做性能测试&#xff0c;如Web应用、数据库和操作系统等。 性能测试种类非常多&#xff0c…

< Linux >缓冲区

在上一篇文件的重定向&#xff0c;通常会涉及文件描述符的操控。文件描述符1&#xff08;fd 1&#xff09;通常代表着标准输出&#xff08;stdout&#xff09;&#xff0c;它默认是指向用户的终端或控制台。当执行文件重定向操作时&#xff0c;如果我们关闭文件描述符1&#xf…

AUTOSAR Builder—符合AUTOSAR(CPAP)的嵌入式系统设计工具

产品概述 AUTOSAR Builder是达索旗下一款基于Eclipse并使用Artop的可扩展工具套件。Artop是由AUTOSAR成员和合作伙伴共同推动的开放的AUTOSAR工具环境。它使用户能够构建自己的工具并与其他工具供应商进行集成。AUTOSAR Builder在此基础上新增了多个工具套件&#xff0c;更加能…

华为HarmonyOS 创建第一个鸿蒙应用 运行Hello World

使用DevEco Studio创建第一个项目 Hello World 1.创建项目 创建第一个项目&#xff0c;命名为HelloWorld&#xff0c;点击Finish 选择Empty Ability模板&#xff0c;点击Next Hello World 项目已经成功创建&#xff0c;接来下看看效果 2.预览 Hello World 点击右侧的预…

INT201 形式语言与自动机笔记(下)

L6 Context-Free Languages 上下文无关语言 Context-Free Grammar (CFG) 是一组用于生成字符串模式的递归规则。上下文无关的语法可以描述所有的常规语言&#xff0c;但它们不能描述所有可能的语言。 e.g 遵循这些规则&#xff0c;我们可以生成一种语言: 上下文无关文法 Co…

热钱涌向线控底盘!XYZ全栈集成引领新风向

在车身、底盘部分&#xff0c;中央计算区域控制带动传统车控、底盘及动力控制ECU市场迎来新一轮技术升级和域融合窗口期。线控制动、转向及空气悬架&#xff0c;正在加速与智能驾驶融合并进一步提升驾乘体验。 12月13-15日&#xff0c;2023&#xff08;第七届&#xff09;高工…

树莓派3B+ /+ CSI摄像头 + FFmpeg + SRS 实现直播推流

简介&#xff1a; 手头有一个树莓派3B 和一块CSI摄像头&#xff0c;想要实现一个推拉流直播的效果。 所需材料&#xff1a;开发板&#xff08;我用的是树莓派3B&#xff09;、CIS摄像头、云服务器&#xff08;用来搭建SRS服务器&#xff09; 具体实现思路&#xff1a; 使用…