news 2026/6/11 15:56:04

FastAPI 接入 FastAPI-Limiter 以及使用 Redis 进行限流指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
FastAPI 接入 FastAPI-Limiter 以及使用 Redis 进行限流指南

fastapi-limiter更新至v0.2.0后与之前不太不一样,这里以接入Redis进行示例说明

安装:

pipinstallredis[hiredis]==7.4.0 pipinstallfastapi-limiter

创建 Redis 管理器

def_get_redis_pool(use_cache_db:bool=True):uri=settings.REDIS_CACHE_URIifuse_cache_dbelsesettings.REDIS_URIreturnredis.ConnectionPool.from_url(uri.encoded_string(),decode_responses=True)redis_client=redis.Redis(connection_pool=_get_redis_pool(False))redis_cache_client=redis.Redis(connection_pool=_get_redis_pool())

注意这里我使用了一个参数来区别 Redis 的 DB,实际上这里的URI来自pydantic,示例如下:

@computed_field@propertydefREDIS_URI(self)->RedisDsn:returnRedisDsn.build(scheme="redis",host=self.REDIS_HOST,port=self.REDIS_PORT,password=self.REDIS_PASSWORDorNone,path=str(self.REDIS_DB))@computed_field@propertydefREDIS_CACHE_URI(self)->RedisDsn:returnRedisDsn.build(scheme="redis",host=self.REDIS_HOST,port=self.REDIS_PORT,password=self.REDIS_PASSWORDorNone,path=str(self.REDIS_CACHE_DB))

创建pyrate_limiter限制器并使用 Redis

因为fastapi-limiter基于pyrate-limiter实现,这里我们需要先创建限制器,然后提供给fastapi_limiter

frompyrate_limiterimportRate,Duration,Limiter,RedisBucket# 用于区分全局和业务的不同限制_GLOBAL_BUCKET_KEY="global-rate-limit"_BIZ_BUCKET_KEY="biz-rate-limit"# 自定义默认限流_DEFAULT_RATES=[Rate(60,Duration.MINUTE),# 60 次每分钟Rate(60*5,Duration.MINUTE*10),# 300 次每十分钟Rate(1000,Duration.HOUR)# 1000 次每小时]defget_redis_limiter(rates:list[Rate]|None=None,is_global:bool=False)->Limiter:ifis_global:bucket_key=_GLOBAL_BUCKET_KEYifnotrates:rates=_DEFAULT_RATESelse:ifnotrates:raiseValueError("Biz limit rate rules cannot be None")bucket_key=_BIZ_BUCKET_KEY# 使用我们已有 redis 管理器中的客户端bucket=RedisBucket.init(rates,redis_client,bucket_key)returnLimiter(bucket)

依赖注入方法

这里可在前置路由依赖中先校验 jwt 后将用户编号或者 ID 放到request.state中,随后依赖该get_rate_limiter方法

须实现用户唯一标识才可用于判断是否登录并用来实现精确流控

fromfastapiimportRequestfromfastapi_limiter.dependsimportRateLimiterfromfastapi_limiter.identifierimportdefault_identifierfrompyrate_limiterimportRateasyncdefget_identifier(request:Request)->str:# 自定义实现逻辑user_no=getattr(request.state,"user_no",None)ifuser_no:returnf"user_{user_no}:{request.scope["path"]}"returnawaitdefault_identifier(request)defget_rate_limiter(rules:list[Rate]|None=None,is_global:bool=False)->RateLimiter:returnRateLimiter(get_redis_limiter(rules,is_global),get_identifier)

路由全局限流

此处示例,假设get_current_user方法中实现了对request.state的用户唯一身份设置,就能轻松区分是否已登录用户并分别限流

get_current_user中应当实现对jwt的解码,拿到用户唯一编号后进行数据库查询,确认无误后设置到request.state(参考逻辑)

fromfastapiimportAPIRouter,Dependsfromapp.api.depsimportget_current_userfromapp.infrastructure.limiter.api_rate_limiterimportget_rate_limiter api=APIRouter(dependencies=[Depends(get_current_user),Depends(get_rate_limiter(is_global=True))])

路由单独限流

由于FastAPIdependencies是叠加的,所以上方RedisBucketkey需要区分

否则在例如发送短信等接口上会因为全局限流已经写入了一条 Redis 记录,导致设置 1 分钟 1 次的限流不可用,会直接触发429请求频繁

这里例如我们有一个发送短信接口:

_SEND_CODE_RATES=[Rate(1,Duration.MINUTE),# 1 次每分钟Rate(5,Duration.HOUR),# 5 次每小时Rate(10,Duration.DAY)# 10 次每天]@router.post("/send-code",dependencies=[Depends(get_rate_limiter(_SEND_CODE_RATES))])asyncdefsend_code():pass

在触发一次短信发送后,会往 Redis 写入两条记录如下:

ZSET Key: global-rate-limit Value: user_123456:/api/send-code:8:1:adee7ca88b:1 ZSET Key: biz-rate-limit Value: user_123456:/api/send-code:8:2:7d2ecd023e:1
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/7 23:50:07

IronyModManager:一键解决Paradox游戏模组冲突的终极方案

IronyModManager:一键解决Paradox游戏模组冲突的终极方案 【免费下载链接】IronyModManager Mod Manager for Paradox Games. Official Discord: https://discord.gg/t9JmY8KFrV 项目地址: https://gitcode.com/gh_mirrors/ir/IronyModManager 你是否曾因Par…

作者头像 李华
网站建设 2026/6/6 19:50:48

【C语言】实现简单动态数组(线程安全)

头文件 #ifndef _CVECTOR_H_ #define _CVECTOR_H_typedef void* cvector;// 初始化 cvector cvector_create(size_t capacity);// 销毁 void cvector_destroy(cvector vector);// 一次性分配内存 size_t cvector_reserve(cvector vector, size_t capacity);// 获取元素个数 siz…

作者头像 李华
网站建设 2026/6/8 0:56:51

Vim 实战:在 VS Code、JetBrains、终端里玩转 Vim

Vim 的精髓不在于“抛弃鼠标”,而在于用键盘语法思考——将“删除”、“复制”、“粘贴”这些动词与“单词”、“段落”、“括号内”这些名词组合,形成一套高效的编辑语言。这套肌肉记忆,可以在几乎所有主流 IDE 中复用。下面我们分三步走&am…

作者头像 李华
网站建设 2026/6/8 5:44:51

告别重复造轮子:用快马AI一键生成高效Token管理工具库

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容: 请生成一个专注于提升Token管理效率的独立工具模块代码。核心功能需求:1、Token生成器:支持可配置的JWT生成,包括密钥、过期时间、签发者、自定…

作者头像 李华
网站建设 2026/6/6 19:43:34

靠谱的设计思考培训机构怎么选?查看资质验证三要素——国际授权、实战师资、名企背书

近年来,设计思考作为一套以人为本的创新方法论,在国内企业、高校乃至个人学习者中受到越来越多的关注。随之而来的是,各类设计思考培训机构如雨后春笋般涌现。然而,课程质量参差不齐、证书含金量难以辨别、“国际认证”头衔真假难…

作者头像 李华
网站建设 2026/6/6 19:41:00

如何选择远心镜头内同轴光源和外同轴光源

机器视觉领域,成像硬件的选择直接影响成像质量,而镜头与光源的搭配更是关键中的关键。许多工程师在实际项目中常面临一个难题:远心镜头内同轴光源和外同轴光源到底如何选择? 今天我们将从原理、效果、适用场景,为你对比…

作者头像 李华