FastAPI 为什么在启动我的FastAPI服务中的uvicorn时会运行我配置方法两次
在本文中,我们将介绍为什么在启动FastAPI服务中的uvicorn时会运行配置方法两次的原因,并提供示例说明。
FastAPI是一个快速(高性能)的Web框架,用于构建API。它使用Python3.7+的类型提示,并支持使用异步(async)和await关键字进行API的高性能处理。
当我们启动FastAPI服务中的uvicorn时,我们期望配置方法只运行一次。但很多开发者可能会遇到配置方法被运行了两次的情况。下面我们来详细解释这个问题的原因。
阅读更多:FastAPI 教程
问题的原因
当我们使用FastAPI和uvicorn构建API时,通常会创建一个FastAPI应用对象,并在uvicorn中运行该应用。我们通常会使用uvicorn.run(app)
来启动服务,其中app
是我们的FastAPI应用对象。
问题在于,uvicorn.run(app)
调用时会初始化我们的应用并运行它,而FastAPI应用的初始化过程中会执行一次配置方法。然而,由于uvicorn的工作原理,它会启动多个工作进程(worker processes)来处理请求。每个工作进程都会独立地初始化FastAPI应用,并执行配置方法。
因此,当我们启动uvicorn时,它会启动多个工作进程,并每个进程都会初始化FastAPI应用和执行配置方法,所以配置方法会运行两次。
解决方法
虽然无法完全避免配置方法运行两次的情况,但我们可以通过一些方法来限制配置方法的执行次数,以避免其中一些不必要的操作。
1. 使用预配置(Preconfigured)应用对象
为了避免每个工作进程都初始化应用并执行配置方法,我们可以提前初始化应用并保存为一个预配置对象。然后,在每个工作进程中,我们可以使用该预配置对象来启动FastAPI应用。
以下是使用预配置应用对象的示例代码:
from fastapi import FastAPI
app = FastAPI()
# 配置方法
def configure_app():
print("Configuring app...") # 示例:输出配置方法执行信息
# 在预配置应用对象上执行配置方法
configure_app()
if __name__ == "__main__":
from uvicorn import run
# 使用预配置应用对象启动FastAPI应用
run(app, host="0.0.0.0", port=8000, workers=4)
在上面的示例中,我们在预配置应用对象app
上首先执行了一次配置方法configure_app()
。然后,在每个工作进程中,我们使用该预配置应用对象app
来启动FastAPI应用,从而避免了重复的配置方法调用。
2. 利用配置标志(Config Flags)
另一种解决办法是使用一个配置标志来控制配置方法的执行次数。我们可以设置一个全局变量,用于标识配置方法是否已经执行过。在配置方法内部,我们可以根据该标志来判断是否执行配置操作。
以下是使用配置标志的示例代码:
from fastapi import FastAPI
app = FastAPI()
# 配置方法
def configure_app():
global already_configured # 全局变量用于标识配置方法是否已经执行
if not already_configured:
print("Configuring app...") # 示例:输出配置方法执行信息
already_configured = True
# 初始化配置标志
already_configured = False
# 在每个工作进程内执行配置方法
configure_app()
if __name__ == "__main__":
from uvicorn import run
# 使用全局变量启动FastAPI应用
run(app, host="0.0.0.0", port=8000, workers=4)
在上面的示例中,我们使用一个全局变量already_configured
来标识配置方法是否已经执行过。在每个工作进程中,我们先检查该变量的值是否为False,如果是则执行配置方法,并将变量设置为True。
总结
在启动FastAPI服务中的uvicorn时,会运行配置方法两次的原因是uvicorn的工作原理:它会启动多个工作进程来处理请求,每个进程都会独立地初始化FastAPI应用并执行配置方法。尽管无法完全避免配置方法运行两次,但我们可以利用预配置应用对象或配置标志来限制配置方法的执行次数,以避免其中一些不必要的操作。
希望本文对您理解FastAPI服务中配置方法运行两次的问题有所帮助,并提供了解决方法。如果您仍然有疑问,请随时查阅FastAPI官方文档或参考相关资源获取更多信息。