一、简介
fastapi-limiter 是一个轻量级、易于集成的库,专为FastAPI设计,用于实现基于令牌桶算法(Token Bucket)的速率限制。此项目由 Long Wang 开发,并且持续维护,旨在提供一个简单而强大的方式来控制应用程序的访问速度。
二、技术分析
fastapi-limiter 的核心功能是通过令牌桶算法来实现限流。该算法允许请求以一定的速率进入,当桶满时,新请求会被拒绝,直到桶内有空位。这一机制使得我们可以灵活地设置每秒请求数(RPS)或每分钟请求数(RPMM),并确保服务稳定运行。
项目采用了标准的FastAPI扩展接口,可以轻松地与其他中间件和装饰器配合使用。同时,fastapi-limiter 支持两种限流模式:
全局限流:对所有客户端统一限速。
IP限流:针对每个客户端(IP地址)单独设定限速,防止某个特定用户过度使用资源。
此外,fastapi-limiter 还提供了详细的统计信息,包括剩余令牌数、重试时间等,方便开发者进行监控和调试。
三、安装使用
1. 安装redis(windows)
1.1 下载压缩包,并解压
Redis-x64-3.2.100https://github.com/microsoftarchive/redis/releases/tag/win-3.2.100
1.2 配置密码
将redis-windows.conf配置文件中的 #requirepass foobared 的#号去掉,将footbared改为自己的密码即可
1.3 配置环境变量
a.打开“高级系统设置”
在“此电脑”上右键,选择“属性”,然后点击“高级系统设置”。
b.进入环境变量设置
在“系统属性”窗口中,点击“环境变量”。
编辑系统环境变量
在“系统变量”区域,选择 Path,然后点击“编辑”。
点击“新建”,输入目录地址(例如:D:\RootRedis),并确认保存
1.4 注册为系统服务
进入redis安装包目录,cmd安装服务,命名为redisserver1:
redis-server.exe --service-install redis.windows.conf --service-name redisserver1 --loglevel verbose
2. 安装fastapi-limiter
从PyPI安装
pip install fastapi-limiter
3. 代码示例
import redis.asyncio as redis
from fastapi import Depends, FastAPI
from fastapi_limiter import FastAPILimiter
from fastapi_limiter.depends import RateLimiter
# 创建一个 FastAPI 实例
app = FastAPI()
# Redis 配置(包括密码)
pool = redis.ConnectionPool.from_url(
"redis://localhost",
encoding='utf-8',
password="yourpassword",
decode_responses=True
)
# Redis 连接(将在启动时创建,在关闭时销毁)
redis_connection = None
# 在应用启动时初始化 Redis 连接和 FastAPILimiter
@app.on_event("startup")
async def startup_event():
global redis_connection
# redis_connection = await redis.create_redis_pool(**redis_config)
# connection_pool = redis.ConnectionPool(**pool)
redis_connection = redis.Redis(connection_pool=pool)
await FastAPILimiter.init(redis_connection)
# 在应用关闭时关闭 Redis 连接
@app.on_event("shutdown")
async def shutdown_event():
if redis_connection:
await redis_connection.close()
# 使用 RateLimiter 装饰器限制访问频率
@app.get("/test", dependencies=[Depends(RateLimiter(times=1, seconds=1))])
async def index():
return {"msg": "Hello World"}
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8081)