You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在uvicorn启动时执行自定义脚本并缓存数据供FastAPI服务使用

实现方案

方案1:使用FastAPI内置的生命周期事件(推荐)

FastAPI本身提供了应用启动前的触发钩子,会在uvicorn加载应用完成、开始对外接收请求之前自动执行,完全匹配预加载缓存的需求。
0.93及以上版本的FastAPI推荐使用lifespan上下文管理器实现:

from fastapi import FastAPI
from contextlib import asynccontextmanager

# 可以是全局内存缓存、Redis连接对象等你用到的缓存载体
cache = {}

@asynccontextmanager
async def lifespan(app: FastAPI):
    # 启动前逻辑:写你的数据库拉取、缓存生成代码
    # 示例:拉取配置表写入缓存
    # config_data = db_session.query(Config).all()
    # for item in config_data:
    #     cache[item.config_key] = item.config_value
    print("缓存预加载完成")
    yield
    # 应用停止时的逻辑(不需要可以不写),比如清理资源、关闭数据库连接

app = FastAPI(lifespan=lifespan)

# 业务接口直接复用缓存即可
@app.get("/get_config")
def get_config(config_key: str):
    return cache.get(config_key)

低版本FastAPI可以用startup事件装饰器实现:

from fastapi import FastAPI

app = FastAPI()
cache = {}

@app.on_event("startup")
def preload_cache():
    # 你的缓存预加载逻辑写这里
    print("缓存预加载完成")

该方案的优势是逻辑和应用绑定,不管用命令行还是代码方式启动uvicorn都会触发,不需要调整启动参数,适配绝大多数场景。

方案2:在uvicorn启动代码中前置执行逻辑

如果你是用Python代码直接启动uvicorn,而非uvicorn命令行启动,可以在调用uvicorn运行前先执行你的预加载逻辑:

import uvicorn
from your_app_file import app

def preload_cache():
    # 你的缓存预加载逻辑
    print("缓存预加载完成")

if __name__ == "__main__":
    # 先执行预加载,再启动服务
    preload_cache()
    uvicorn.run(app, host="0.0.0.0", port=8000)

该方案适合多worker部署、且缓存为全局共享(比如Redis、共享内存)的场景,预加载逻辑只会在主进程执行一次,不会每个worker重复运行。如果你的缓存是worker本地内存存储,还是选择方案1更合适,会自动在每个worker启动时各执行一次预加载。

注意事项

  • 多worker部署时先明确你的需求:全局只预加载一次选方案2,每个worker都要生成本地缓存选方案1
  • 预加载逻辑耗时较长时建议加进度日志,避免误判为启动卡住
  • 预加载失败时建议直接抛出异常终止启动,避免服务运行后缓存不可用导致业务异常

内容的提问来源于stack exchange,提问作者user1591156

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 19:15:06