生命周期与事件
前言
startup 和 shutdown 事件是 FastAPI 提供的在服务启动和关闭时执行的事件回调处理机制,常用于连接数据库、加载配置、启动/停止后台任务等。
注意
旧版本的 on_event 方法已经废弃,当前应使用 lifespan(本笔记已验证于 FastAPI 0.141.1)。
示例代码
from contextlib import asynccontextmanager
from fastapi import FastAPI
@asynccontextmanager
async def lifespantest(app: FastAPI):
print("--> 服务启动")
# 启动阶段的初始化(连接数据库、加载配置、启动后台任务等)放在 yield 之前
try:
yield
finally:
# 关闭阶段的清理(关闭连接、停止任务等)放在 finally 中,保证异常时也会执行
print("<-- 服务停止")
app = FastAPI(
title=settings.title,
description=settings.description,
version=settings.version,
docs_url=None,
debug=settings.debug,
lifespan=lifespantest,
)
要点:
yield之前执行启动逻辑,yield之后执行关闭逻辑;用try/finally包裹可以保证关闭逻辑在异常时也执行。- 在 lifespan 中创建的资源(如数据库引擎、Redis 连接)可以通过
app.state或依赖注入供路由使用。
示例运行输出:
INFO: Started server process [2214]
INFO: Waiting for application startup.
--> 服务启动
INFO: Application startup complete.
INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
^CINFO: Shutting down
INFO: Waiting for application shutdown.
<-- 服务停止
INFO: Application shutdown complete.
INFO: Finished server process [2214]
结合 app.state 共享资源
在 lifespan 中初始化的资源(数据库引擎、Redis 客户端、队列等)推荐挂在 app.state 上,路由中通过 request.app.state.xxx 访问:
from contextlib import asynccontextmanager
from fastapi import FastAPI, Request
@asynccontextmanager
async def lifespan(app: FastAPI):
# 启动时初始化资源
app.state.redis_client = await create_redis_client()
yield
# 关闭时清理资源
await app.state.redis_client.close()
app = FastAPI(lifespan=lifespan)
@app.get("/")
async def index(request: Request):
# 路由中访问 app.state 上的共享资源
uptime = request.app.state.redis_client.get("uptime")
return {"uptime": uptime}
提示
完整的 Redis 连接池与 lifespan 结合示例见 连接数据库;基于 lifespan 启动后台消费者池/定时调度器的完整项目见 补充:异步处理数据 与 补充:基于 DB 的分布式锁。