FastAPI 项目启动/关闭事件实战:数据库连接、缓存预热、模型加载一站式搞定!
在生产环境中,我们经常会遇到这样的需求:
项目启动时,需要连接数据库、加载机器学习模型或预热缓存项目关闭时,需要优雅释放连接、清理资源,确保不会“僵尸占用”好消息是:FastAPI 原生就支持启动与关闭事件机制(startup/shutdown),而且使用起来异常优雅!
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("应用关闭,释放资源...")1.2.3.4.5.6.7.8.9.10.11.
方法二:使用 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)1.2.3.4.5.6.7.8.9.10.11.12.
我们将模拟如下生命周期管理需求:
场景
操作
启动时
连接数据库、预热缓存、加载模型
关闭时
关闭数据库连接、清空缓存
示例结构:
复制
project/
├── main.py
├── utils/
│ ├── database.py
│ ├── cache.py
│ └── model_loader.py1.2.3.4.5.6.
1. 模拟数据库连接模块:database.py
复制
# 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()1.2.3.4.5.6.7.8.9.10.11.12.13.14.
2. 模拟缓存模块:cache.py
复制
# utils/cache.py
cache = {}
async def preload_cache():
print("⚡ 预热缓存中...")
cache["hot_data"] = [1, 2, 3, 4]
async def clear_cache():
print("🧹 清理缓存...")
cache.clear()1.2.3.4.5.6.7.8.9.10.
3. 模拟模型加载模块:model_loader.py
复制
# utils/model_loader.py
model = None
async def load_model():
global model
print("🤖 加载机器学习模型...")
model = "MyModel"
async def unload_model():
global model
print("🧼 卸载模型...")
model = None1.2.3.4.5.6.7.8.9.10.11.12.
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 生命周期!"}1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.
启动应用后你会看到类似输出:
复制
🔌 正在连接数据库...
⚡ 预热缓存中...
🤖 加载机器学习模型...1.2.3.
关闭应用时:
复制
❌ 正在关闭数据库连接...
🧹 清理缓存...
🧼 卸载模型...1.2.3.
FastAPI 的生命周期事件非常适合处理启动初始化与资源释放的场景:
lifespan() 是更现代、推荐的方式支持 异步资源初始化,天然适配 async 框架非常适合用于加载模型、连接 Redis、数据库、Kafka、RabbitMQ 等阅读剩余
THE END