如何在Python中基于Django中间件实现接口访问频率限流

夜芳姑娘_2215

夜芳姑娘_2215

2026-10-04

222人浏览

原创

django-ratelimit不够用因其限流维度单一、装饰器难以统一拦截各类视图,而中间件可早于权限校验介入,结合可配置策略(如路径前缀映射限流规则)、多维键名(ip+用户id等)及redis lua原子脚本,实现生产级精准限流。

如何在python中基于django中间件实现接口访问频率限流

为什么直接用 django-ratelimit 不够用

因为它的默认后端只支持内存或 Redis,但生产环境常需要按用户角色、API 分组、甚至 IP+Token 组合维度限流;django-ratelimit 的装饰器写法也难以统一拦截所有 API(比如 DRF 的 APIView 子类、函数视图、Schema 视图),中间件能更早介入请求生命周期,避免路由解析开销。

如何在中间件里做「可配置」的限流判断

关键不是硬编码规则,而是把限流策略抽成配置项,让每个路径/方法/用户类型走不同规则。示例中用字典映射路径前缀到限流参数:

RATE_LIMIT_CONFIG = {
    r"^/api/v1/orders/": {"window": 60, "limit": 10, "key_func": "ip_and_user_id"},
    r"^/api/v1/search/": {"window": 60, "limit": 30, "key_func": "ip_only"},
    r"^/api/v1/admin/": {"window": 300, "limit": 5, "key_func": "token_header"},
}

中间件里用 re.match 匹配请求路径,查出对应规则;key_func 决定限流键名(如 "ip:192.168.1.100:user:123"),避免简单用 IP 导致登录用户被误限。

  • 别用 request.path_info 做精确匹配——它不含查询参数,但限流通常不关心 query,所以够用
  • window 和 limit 必须存为整数,字符串会引发 Redis incr 操作失败
  • 如果用 Redis 后端,键名建议加前缀如 f"rl:{key}",避免和其他业务 key 冲突

Redis 计数器怎么防并发超限

Django 中间件本身无状态,必须依赖外部存储计数。Redis 是最常用选择,但直接用 INCR + EXPIRE 有竞态风险:两个请求同时读到 0,都执行 INCR,结果变成 2,但只设了一次过期时间。

Li Python Sec Check
Li Python Sec Check

Python 安全规范检查工具:基于 CloudBase 规范、腾讯安全指南,LLM 智能分析(默认禁用,优先本地执行)

下载

正确做法是用 Lua 脚本原子执行「增+判+设过期」:

lua_script = """
local current = redis.call("incr", KEYS[1])
if current == 1 then
    redis.call("expire", KEYS[1], tonumber(ARGV[1]))
end
return current
"""

调用时传入 key 和 window 秒数:redis_client.eval(lua_script, 1, key, window)。返回值就是当前计数,超过 limit 就直接返回 429。

  • 别用 cache.set(key, value, timeout) —— 它无法原子判断是否首次设置
  • 如果 Redis 连接失败,建议 fallback 到放行(非阻断),否则整个服务可能雪崩
  • 测试时可用 django.core.cache.cache 的 dummy backend,但上线必须切到 Redis

DRF 和普通视图混用时如何统一拦截

中间件对所有请求一视同仁,但 DRF 的 APIView 可能已通过 permission_classes 拦截了未认证请求,而限流应在权限校验前触发(否则攻击者可反复用错误 token 触发鉴权逻辑)。所以中间件位置很重要:

确保它放在 MIDDLEWARE 列表中 SessionMiddleware 和 AuthenticationMiddleware 之后、但 CommonMiddleware 之前。这样能拿到 request.user(如果是已认证用户),又不会因权限拒绝而跳过限流。

  • 对未登录用户,request.user.is_authenticated 为 False,此时应退化到 IP 或 header 提取的 token 字段
  • 若接口允许匿名访问(如公开搜索),务必限制 IP 级别,否则容易被爬虫打穿
  • 不要在中间件里调用 request.data 或 request.query_params —— DRF 的解析逻辑尚未执行,会触发异常
限流键的设计粒度和 Redis 脚本的原子性,是线上最容易出问题的两个点。前者导致该限没限、不该限的被限;后者导致计数漂移,实际 QPS 远超配置值。

Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

python django

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
python打包成可执行文件
python打包成可执行文件

本专题为大家带来python打包成可执行文件相关的文章,大家可以免费的下载体验。

2023.07.20

1651

4

python能做什么
python能做什么

python能做的有:可用于开发基于控制台的应用程序、多媒体部分开发、用于开发基于Web的应用程序、使用python处理数据、系统编程等等。本专题为大家提供python相关的各种文章、以及下载和课程。

2023.07.25

4064

7

format在python中的用法
format在python中的用法

Python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.07.31

1649

3

python教程
python教程

Python已成为一门网红语言,即使是在非编程开发者当中,也掀起了一股学习的热潮。本专题为大家带来python教程的相关文章,大家可以免费体验学习。

2023.08.03

23437

23

python环境变量的配置
python环境变量的配置

Python是一种流行的编程语言,被广泛用于软件开发、数据分析和科学计算等领域。在安装Python之后,我们需要配置环境变量,以便在任何位置都能够访问Python的可执行文件。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.04

2867

5

python eval
python eval

eval函数是Python中一个非常强大的函数,它可以将字符串作为Python代码进行执行,实现动态编程的效果。然而,由于其潜在的安全风险和性能问题,需要谨慎使用。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.04

2907

5

scratch和python区别
scratch和python区别

scratch和python的区别:1、scratch是一种专为初学者设计的图形化编程语言,python是一种文本编程语言;2、scratch使用的是基于积木的编程语法,python采用更加传统的文本编程语法等等。本专题为大家提供scratch和python相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.11

1143

5

python合并两个列表
python合并两个列表

Python是一种强大的编程语言,具有许多方便的功能和工具。在Python中,有多种方法可以合并两个列表。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.10

596

4

python是前端还是后端
python是前端还是后端

Python属于前端也属于后端,其灵活性和丰富的生态系统使得开发人员能够在不同的领域中灵活运用。本专题为大家提供python相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.11

2263

5

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程