FastAPI 项目启动/关闭事件实战:数据库连接、缓存预热、模型加载一站式搞定!
在实际开发中,我们常常会遇到这样的需求:
- ✅ 项目启动时,需要初始化数据库连接、加载机器学习模型、预热缓存等;
- ✅ 项目关闭时,需要优雅释放资源,防止“僵尸进程”或资源泄露。
好消息是:FastAPI 原生支持生命周期事件机制(startup/shutdown),而且实现方式十分优雅!
🔧 一、FastAPI 的生命周期事件机制简介
FastAPI 提供两种方式来注册生命周期事件:
方法一:使用 @app.on_event()
装饰器(经典方式)
from fastapi import FastAPI
app = FastAPI()
@app.on_event("startup")
async def startup_event():
print("应用启动,初始化资源...")
@app.on_event("shutdown")
async def shutdown_event():
print("应用关闭,释放资源...")
方法二:使用 lifespan()
上下文函数(推荐方式)
自 FastAPI 1.0 起,更推荐使用 lifespan
函数统一管理生命周期,更清晰、更灵活。
from fastapi import FastAPI
from contextlib import asynccontextmanager
@asynccontextmanager
async def lifespan(app: FastAPI):
print("✅ 应用启动 - startup")
# 初始化资源
yield
print("🧹 应用关闭 - shutdown")
# 清理资源
app = FastAPI(lifespan=lifespan)
🧪 二、实战演练:数据库 + 缓存 + 模型加载
我们模拟一个真实的应用场景:
场景阶段 | 操作内容 |
---|---|
启动时 | 连接数据库、预热缓存、加载模型 |
关闭时 | 关闭数据库连接、清空缓存、卸载模型 |
📁 项目结构示例
project/
├── main.py
├── utils/
│ ├── database.py
│ ├── cache.py
│ └── model_loader.py
🔌 1. 数据库连接模块 utils/database.py
class DBClient:
def __init__(self):
self.connected = False
async def connect(self):
print("🔌 正在连接数据库...")
self.connected = True
async def disconnect(self):
print("❌ 正在关闭数据库连接...")
self.connected = False
db_client = DBClient()
⚡ 2. 缓存模块 utils/cache.py
cache = {}
async def preload_cache():
print("⚡ 预热缓存中...")
cache["hot_data"] = [1, 2, 3, 4]
async def clear_cache():
print("🧹 清理缓存...")
cache.clear()
🤖 3. 模型加载模块 utils/model_loader.py
model = None
async def load_model():
global model
print("🤖 加载机器学习模型...")
model = "MyModel"
async def unload_model():
global model
print("🧼 卸载模型...")
model = None
🧠 4. 应用入口 main.py
from fastapi import FastAPI
from contextlib import asynccontextmanager
from utils.database import db_client
from utils.cache import preload_cache, clear_cache
from utils.model_loader import load_model, unload_model
@asynccontextmanager
async def lifespan(app: FastAPI):
# 应用启动逻辑
await db_client.connect()
await preload_cache()
await load_model()
yield
# 应用关闭逻辑
await db_client.disconnect()
await clear_cache()
await unload_model()
app = FastAPI(lifespan=lifespan)
@app.get("/")
async def root():
return {"message": "Hello, FastAPI 生命周期!"}
✅ 控制台运行效果
当你启动 FastAPI 应用时,将看到如下输出:
🔌 正在连接数据库...
⚡ 预热缓存中...
🤖 加载机器学习模型...
关闭应用时:
❌ 正在关闭数据库连接...
🧹 清理缓存...
🧼 卸载模型...
✍️ 总结
FastAPI 的生命周期事件机制为异步初始化和资源管理提供了极大的便利:
- ✅
lifespan()
是更推荐、更现代的做法 - ✅ 完美支持异步资源初始化(async/await)
- ✅ 非常适合管理数据库连接、缓存系统、机器学习模型加载、消息队列连接等资源
在实际项目中,合理使用 lifespan()
,可以大幅提升项目的可维护性和健壮性。