跳到主要内容

生命周期与事件

前言

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 的分布式锁

参考