频率限制

本文详细解析了如何自定义实现REST框架中的访问频率控制,通过创建一个MyThrottle类来限制同一IP在一分钟内的访问次数不超过三次,同时提供了在设置文件中配置全局或局部使用的示例。

自定义,也是源码的基本逻辑

'''
    {'ip1':[时间1 ,时间2],
    'ip2':[时间1, ],
    }
   #(1)取出访问者ip
    # (2)判断当前ip不在访问字典里,添加进去,并且直接返回True,表示第一次访问,在字典里,继续往下走
    # (3)循环判断当前ip的列表,有值,并且当前时间减去列表的最后一个时间大于60s,把这种数据pop掉,这样列表中只有60s以内的访问时间,
    # (4)判断,当列表小于3,说明一分钟以内访问不足三次,把当前时间插入到列表第一个位置,返回True,顺利通过
    # (5)当大于等于3,说明一分钟内访问超过三次,返回False验证失败
'''

class MyThrottle():
    visitor_dic = {}

    def __init__(self):
        self.history = None

    def allow_request(self, request, view):
        ip = request.META.get('REMOTE_ADDR')     # 拿出ip地址,固定写法
        # 不在字典中,说明是第一次访问
        ctime = time.time()
        if ip not in self.visitor_dic:
            self.visitor_dic[ip] = [ctime, ]
            return True
        # 根据当前访问者ip,取出访问的时间列表
        history = self.visitor_dic[ip]
        self.history = history
        while history and ctime - history[-1] > 60:    #循环取,最后一个判断大于60,取倒数第二个,
            history.pop()

        if len(history) < 3:
            # 把当前时间放到第0个位置上
            history.insert(0, ctime)
            return True

        return False

    def wait(self):
        # 剩余时间
        ctime = time.time()
        return 60 - (ctime - self.history[-1])
View Code

 

使用

-内置的访问频率控制类SimpleRateThrottle
-写一个类,继承SimpleRateThrottle
-class MyThrottle(SimpleRateThrottle):
    scope='aaa'    #这里的aaa必须与setting中的aaa对应
    def get_cache_key(self, request, view):
        return self.get_ident(request)
-在setting中:
    REST_FRAMEWORK = {
        'DEFAULT_THROTTLE_RATES':{
            'aaa':'10/m'      #与scope的对应处,
        }                               
    }
#后边的参数分析:10是访问次数,后边的是这里边的任意一个
                                       #{'s': 1, 'm': 60, 'h': 3600, 'd': 86400}



------------------------------------
-使用
#1、局部使用:
在视图类中写
    throttle_classes = [MyThrottle,]

#2、全局使用:
在setting中:
    REST_FRAMEWORK = {
        'DEFAULT_THROTTLE_CLASSES':['app01.MyAuth.MyThrottle',],
        'DEFAULT_THROTTLE_RATES':{
            'aaa':'10/m'
        }
    }

#3、局部禁用:
    在视图类中写
    throttle_classes = []


---------------------------------------
#错误信息改成中文显示:(在视图类中写)
    def throttled(self, request, wait):
        class MyThrottled(exceptions.Throttled):
            default_detail = '请稍候'
            extra_detail_singular = '还剩 {wait} 秒.'
            extra_detail_plural = '还剩 {wait} 秒'

        raise MyThrottled(wait)

 

源码分析

有时间了整理

 

转载于:https://www.cnblogs.com/pdun/p/11249550.html

### 如何在 Redis 中实现频率限制 #### 频率限制的基本概念 频率限制是一种常见的技术手段,用于防止系统被滥用或过载。它通常应用于 API 请求、登录尝试或其他可能引发高负载的操作场景中。通过设置单位时间内的最大请求次数,可以有效地保护系统的稳定性和安全性。 #### 使用 Redis 实现频率限制的优势 由于 Redis 是一种高性能的内存数据库[^3],其快速的数据存取能力使其成为实现频率限制的理想工具。Redis 提供了丰富的数据结构和原子操作支持,这使得开发者能够轻松构建高效的限流机制。 --- #### 常见的限流算法及其应用 以下是几种常用的限流算法: 1. **固定窗口计数器** - 这是最简单的限流方法之一。在一个固定的周期内记录请求次数,当达到设定阈值时拒绝后续请求。 - 虽然简单易懂,但在窗口切换时可能会导致突发流量问题。 2. **滑动窗口计数器** - 改进了固定窗口计数器的时间粒度问题,允许更平滑地处理请求分布。 - 可以通过 Redis 的有序集合(Sorted Set)来模拟滑动窗口的效果。 3. **令牌桶算法** - 系统按照恒定速率向桶中添加令牌,每次请求消耗一个令牌。如果桶为空,则拒绝请求。 - Redis 的 `INCR` 和 `EXPIRE` 命令非常适合用来实现这一逻辑。 4. **漏桶算法** - 类似于令牌桶,但它以固定速率释放请求,适合对延迟敏感的应用程序。 - 同样可以通过 Redis 来维护队列长度和超时策略。 --- #### 具体实现示例:基于令牌桶算法的频率限制 下面是一个使用 Java 结合 Redis 实现令牌桶算法的例子: ```java import redis.clients.jedis.Jedis; public class RateLimiter { private final Jedis jedis; private final String keyPrefix = "rate_limit:"; public RateLimiter(Jedis jedis) { this.jedis = jedis; } /** * 判断当前用户是否超过频率限制 * * @param userId 用户唯一标识符 * @return true 表示未超出限制;false 表示已超出限制 */ public boolean allowRequest(String userId, int maxRequestsPerMinute) { String key = keyPrefix + userId; long currentTime = System.currentTimeMillis(); long bucketSizeMs = 60_000; // 每分钟 // 获取剩余的有效令牌数量 Long remainingTokens = jedis.get(key); if (remainingTokens == null || remainingTokens <= 0) { // 初始化新的令牌桶 jedis.setex(key, bucketSizeMs / 1000, String.valueOf(maxRequestsPerMinute)); return true; } else { // 减少一个令牌并更新有效期 jedis.decr(key); jedis.expire(key, bucketSizeMs / 1000); return remainingTokens > 0; } } } ``` 上述代码展示了如何利用 Redis 的键值存储功能以及原子操作特性来实现动态调整的频率限制[^1]。 --- #### 监控与优化 为了确保频率限制方案的实际效果,还需要定期检查 Redis 的资源占用情况。例如,可以通过执行以下命令获取内存使用详情: ```bash INFO MEMORY MEMORY USAGE <key> ``` 这些信息有助于评估是否存在潜在瓶颈,并及时作出相应调整[^2]。 此外,在分布式环境中部署 Redis 时,应考虑采用 Redlock 算法解决跨实例同步问题,从而进一步提升整体可靠性[^4]。 --- #### 总结 综上所述,借助 Redis 的高效特性和多种内置指令,开发人员可以根据具体需求灵活设计不同的频率限制策略。无论是单机还是集群模式下,只要合理规划架构并遵循最佳实践指南,就能显著增强应用程序的安全防护水平。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值