zoukankan      html  css  js  c++  java
  • drf源码分析系列---节流(访问频率限制)

    使用

    from rest_framework.throttling import AnonRateThrottle
    from rest_framework.generics import ListAPIView,CreateAPIView,UpdateAPIView,DestroyAPIView,RetrieveAPIView
    from api.serializer.articleserializer import ArticleSerializer
    from api import models
    class ArticleAPIView(ListAPIView):
        authentication_classes = []
        throttle_classes = [AnonRateThrottle, ] #给改类设置频率限制,当访问改视图对应的路由时会有频率限制
        queryset = models.Article.objects.all()
        serializer_class = ArticleSerializer
    
    setting.py频率限制
    REST_FRAMEWORK = {
        "DEFAULT_THROTTLE_RATES":{
            "anon":'10/m' #1分钟访问3次
        }
    }
    

    节流的原理

    当我们请求进来,走到我们频率组件的时候,DRF内部会有一个字典来记录访问者的IP,
    	以这个访问者的IP为key,value为一个列表,存放访问者每次访问的时间,
    	# { IP1: [第三次访问时间,第二次访问时间,第一次访问时间],}
    	把每次访问最新时间放入列表的最前面,记录这样一个数据结构后,通过什么方式限流呢~~
    
    如果我们设置的是10秒内只能访问5次,
      1,判断访问者的IP是否在这个请求IP的字典里
      2,保证这个列表里都是最近10秒内的访问的时间
         判断当前请求时间和列表里最早的(也就是最后的)
          如果差大于10秒,说明请求以及不是最近10秒内的,删除掉,继续判断倒数第二个,直到差值小于10秒
      3,判断列表的长度(即访问次数),是否大于我们设置的5次,
         如果大于就限流,否则放行,并把时间放入列表的最前面
    

    节流的源码分析

    执行流程

    1.请求进来执行dispatch方法中的initialize_request方法
        def initialize_request(self, request, *args, **kwargs):
            parser_context = self.get_parser_context(request)
    
            return Request(
                request,
                parsers=self.get_parsers(),
                authenticators=self.get_authenticators(),
                negotiator=self.get_content_negotiator(),
                parser_context=parser_context
            )
        
    
    2.执行inital
        def initial(self, request, *args, **kwargs):
    		.......略过的代码
            version, scheme = self.determine_version(request, *args, **kwargs)
            request.version, request.versioning_scheme = version, scheme
    
            self.perform_authentication(request) #认证函数
            self.check_permissions(request)  #权限函数
            self.check_throttles(request)  #节流函数
    
    3.执行check_throttles(request)函数
        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())
    
    	3.1get_throttles函数
        def get_throttles(self):
            return [throttle() for throttle in self.throttle_classes]
    	3.2执行allow_request(request, self)
    
    4.然后就执行了节流的原理的逻辑代码
    

  • 相关阅读:
    Apache Shiro和Spring Security的详细对比
    Oauth2.0 用Spring-security-oauth2 来实现
    引入AOP 报错 error at ::0 formal unbound in pointcut
    日记网站收藏
    Spring 在web 容器中的启动过程
    knockoutjs如何动态加载外部的file作为component中的template数据源
    ORACLE触发器详解
    浅谈数据库分表
    HTTP协议详解(真的很经典)
    ThinkPHP的四种URL模式 URL_MODEL
  • 原文地址:https://www.cnblogs.com/tangjian219/p/11913846.html
Copyright © 2011-2022 走看看