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("應用關閉,釋放資源...")
方法二:使用 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. 模擬數據庫連接模塊: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()
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()
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 = 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 的生命周期事件非常適合處理啟動初始化與資源釋放的場景:
- lifespan() 是更現代、推薦的方式
- 支持 異步資源初始化,天然適配 async 框架
- 非常適合用于加載模型、連接 Redis、數據庫、Kafka、RabbitMQ 等