ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

django中限流器使用

2021-02-21 15:04:01  阅读:194  来源: 互联网

标签:__ ctime self request django 访问 限流 使用 history



#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
__title__ = ''
__author__ = ''
__mtime__ = ''
"""
import logging
import time
from rest_framework.throttling import SimpleRateThrottle

logger = logging.getLogger('mylogger')


class VisitThrottleMixin(object):
    '''
    根据Django-rest-framework的限流原理改写,根据滚动时间分片限流,应对瞬时高并发
    有一定的局限性
    作者:
    '''
    # 60s内可以访问最大次数
    MAX_CAPACITY = 1
    # 设置超时时间
    TIME_DELTA = 60

    def __init__(self):
        # 用于await计算剩余访问时间
        self.history = None
        self.__visit_key = '__visit_throttle_key'

    def allow_request(self, request, view):
        mehtod = request.method
        uri_name = request.path_info
        if mehtod == "POST" and uri_name == "/xxx/xxx/":
            ctime = time.time()
            # 用户第一次访问,将其进行记录,并且返回True,允许继续访问
            if self.__visit_key not in request.session:
                request.session[self.__visit_key] = [ctime, ]
                return True
            # 如果不是第一次访问,获取所有的记录在
            history = request.session.get(self.__visit_key)
            self.history = history
            # 如果有历史访问记录,并且最早一次的访问记录离当前时间超过60s,就删除最早的那个访问记录,
            # 只要为True,就一直循环超过60s就删除最早的一次访问记录
            while history and history[-1] < (ctime - self.TIME_DELTA):
                history.pop()
            # 如果访问记录不超过MAX_CAPACIRY次,就把当前的访问记录插到第一个位置(pop删除最后一个)
            if len(history) < self.MAX_CAPACITY:
                history.insert(0, ctime)
                request.session[self.__visit_key] = history
                return True
            return False
        else:
            return True

    def wait(self):
        '''还需要等多久才能访问'''
        ctime = time.time()
        return self.TIME_DELTA - (ctime - self.history[-1])


VISIT_RECORD = {}  # 定义全局变量,用于存放访问记录


class VisitThrottle(object):
    # 60s内可以访问最大次数
    MAX_CAPACITY = 1
    # 设置超时时间
    TIME_DELTA = 60

    def __init__(self):

        # 用于await计算剩余访问时间
        self.history = None

    def allow_request(self, request, view):
        # 获取用户ip作为唯一的标示
        if request.META.get('HTTP_X_FORWARDED_FOR'):
            remote_addr = request.META.get("HTTP_X_FORWARDED_FOR")
        else:
            remote_addr = request.META.get('REMOTE_ADDR')

        # 获取当前访问的时刻
        ctime = time.time()
        # 这是用户第一次访问,将其进行记录,并且返回True,允许继续访问
        if remote_addr not in VISIT_RECORD:
            VISIT_RECORD[remote_addr] = [ctime, ]
            return True

        # 如果不是第一次访问,获取所有的记录
        history = VISIT_RECORD.get(remote_addr)

        self.history = history
        # 判断最开始的时刻与现在的时刻的差值是否在规定的时间范围内,比如在60s内,如果不在,
        # 可以去除最开始的时刻记录
        while history and history[-1] < ctime - self.TIME_DELTA:
            history.pop()
        # 此时列表中的时刻记录都是在规定的时间范围内,判断时刻的个数也就是访问的次数

        if len(history) < self.MAX_CAPACITY:
            history.insert(0, ctime)
            return True

    def wait(self):
        # 还需要等多少秒才能访问
        ctime = time.time()
        return self.TIME_DELTA - (ctime - self.history[-1])

标签:__,ctime,self,request,django,访问,限流,使用,history
来源: https://blog.csdn.net/s_daqing/article/details/113918088

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有