如何在Python中使用Django REST framework实现API限流?

酷辰小哥_6644

酷辰小哥_6644

2026-11-02

187人浏览

原创

优先选AnonRateThrottle(仅限匿名用户),因其是SimpleRateThrottle的预置子类、开箱即用;需按用户角色、路径或租户等自定义限流时,必须继承SimpleRateThrottle并重写get_cache_key()。

如何在python中使用django rest framework实现api限流?

限流类怎么选:SimpleRateThrottle 还是 AnonRateThrottle?

Django REST framework(DRF)内置的限流机制依赖于继承 BaseThrottle 的类,最常用的是 SimpleRateThrottle。它支持自定义限流逻辑,比如按用户 ID、IP 或请求路径区分;而 AnonRateThrottle 和 UserRateThrottle 只是它的子类,分别针对未认证和已认证用户做了默认实现。

  • 如果你只需要对匿名用户限流,直接用 AnonRateThrottle 最省事
  • 如果要按用户角色、租户 ID 或 API 路径做差异化限流,必须继承 SimpleRateThrottle 并重写 get_cache_key()
  • 不要用 UserRateThrottle 处理匿名请求——它对 request.user.is_authenticated == False 返回 None,导致该请求完全绕过限流

注意:所有限流类都依赖 DRF 的缓存后端(如 Redis 或 LocMemCache),如果没配缓存,SimpleRateThrottle 会退化为每请求都查数据库(极慢),甚至抛出 RuntimeError: No cache backend configured。

如何配置 rate 字符串:"100/day" 的语法细节

DRF 限流的速率由字符串控制,格式为 "/",其中 period 必须是 second、minute、hour 或 day(不支持复数或缩写,"100/min" 会报错)。

  • "5/minute" 表示每分钟最多 5 次请求(从第一次触发开始计时,不是自然分钟)
  • "100/hour" 实际对应一个滑动窗口:DRF 内部用时间戳 + 计数器实现,不是固定整点重置
  • 多个限流规则可叠加,比如同时声明 AnonRateThrottle 和 UserRateThrottle,任一触发即拒绝请求
  • 若想对某个视图单独设限,不要改全局 DEFAULT_THROTTLE_CLASSES,而是直接在视图类里写:throttle_classes = [MyCustomThrottle]

常见错误:把 rate = "100/day" 写成 rate = "100 per day" ——中间空格或多余字符会导致解析失败,静默失效(请求永远不被限)。

自定义限流:按 request.path 或 tenant_id 区分流量

当需要“每个租户每天最多调用 /api/v1/orders/ 接口 1000 次”,就得自己写限流类:

python-flask-vue-creator
python-flask-vue-creator

创建 Flask + Vue.js 全栈项目,采用单端口架构、uv 依赖管理、结构化日志和生产级前端设计。当用户要求以下操作时触发:创建新的 Flask+Vue 项目、搭建 Web 应用、构建全栈 Python+Vue 应用、初始化 Flask Web 项目、设置单端口 Flask 前后端项目。触发词:新建项目、创建项目、搭建项目、Flask项目、Vue项目。

下载
class TenantPathThrottle(SimpleRateThrottle):
    scope = 'tenant_path'
<pre class="brush:python;toolbar:false;">def get_cache_key(self, request, view):
    if not request.user.is_authenticated:
        return None
    # 组合租户ID + 请求路径作为唯一key
    tenant_id = getattr(request.user, 'tenant_id', 'unknown')
    path = request.path
    return f'throttle_{tenant_id}_{path}'
  • scope 是缓存 key 前缀,必须和 settings.py 中的 THROTTLE_RATES 键名一致
  • get_cache_key() 返回 None 表示跳过限流(比如对登录接口放行)
  • 切勿在 get_cache_key() 里做数据库查询——它在每次请求前调用,会成为性能瓶颈
  • 如果用 Redis 缓存,key 实际存储为 throttle_/api/v1/orders/,可用 redis-cli keys "throttle*" 检查

容易忽略的一点:DRF 默认用 cache.set(key, value, timeout) 存储计数,但 timeout 是硬编码的(如 minute 对应 60 秒)。如果你改了系统时间或用了时钟漂移大的容器,可能导致限流窗口错乱。

调试限流失败:为什么 X-RateLimit-Remaining 总是 -1?

DRF 会在响应头中添加 X-RateLimit-Limit、X-RateLimit-Remaining 和 X-RateLimit-Reset,但这些字段只在启用限流且缓存正常时才出现。

  • 如果响应头里没有这些字段,先确认视图是否真的应用了限流类(print(view.throttle_classes))
  • X-RateLimit-Remaining: -1 表示当前请求已被拒绝(HTTP 429),但 DRF 仍会写入响应头
  • 本地开发用 LocMemCache 时,不同进程间缓存不共享,多开几个终端测试会误判为“没生效”
  • 真实环境务必用 Redis,并确保 CACHES 配置中的 KEY_PREFIX 不为空(否则多个服务实例可能 key 冲突)

最隐蔽的问题:限流类的 allow_request() 方法抛异常(比如访问了不存在的 request.auth 属性)会导致整个请求 500,而不是 429——这种错误不会打日志,只能靠单元测试覆盖。

大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!

相关文章

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

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

下载

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

相关专题

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

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

2023.07.20

1851

4

python能做什么
python能做什么

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

2023.07.25

5024

7

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

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

2023.07.31

1809

3

python教程
python教程

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

2023.08.03

30177

23

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

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

2023.08.04

3587

5

python eval
python eval

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

2023.08.04

3607

5

scratch和python区别
scratch和python区别

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

2023.08.11

1243

5

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

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

2023.08.10

616

4

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

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

2023.08.11

2803

5

热门下载

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

精品课程

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