docker 在侦听端口之前完全初始化fastapi Web服务

xeufq47z  于 2023-03-17  发布在  Docker
关注(0)|答案(1)|浏览(112)

我有一个fastapi网络应用程序,它运行在一个docker容器中,这个网络应用程序托管了多个机器学习模型,在启动时它需要将这些模型读入内存,这个过程大约需要30秒。
我试图实现的是让容器在监听任何请求之前启动并加载所有的模型、类等。这很有用,因为在谷歌云运行这样的平台上,在容器必须开始监听流量之前,你最多有4分钟的启动时间。现在我的容器在这种启动模式下会丢弃任何流量。
我想知道是否有一种方法可以实现这一点,无论是一些 Docker 或fastapi魔术!

zxlwwiss

zxlwwiss1#

是的,这是可以实现的!在这两个解决方案中,FastAPI将不会开始服务请求,直到启动逻辑(在您的情况下,加载一个ML模型)完成。
实际上,在启动逻辑完成之前,应用不会开始侦听所选端口,并且由于您在Google Cloud Run平台上运行应用,因此在此之前,应用不会向您的应用提供流量。

如果您使用的FastAPI版本〈0.93.0

您应该在“启动事件处理程序”中加载您的模型。例如:

from fastapi import FastAPI

def fake_answer_to_everything_ml_model(x: float):
    return True

ml_models = {}

app = FastAPI()

@app.on_event("startup")
async def app_startup():
    # Load your ML model:
    ml_models["answer_to_everything"] = fake_answer_to_everything_ml_model

如果您使用的FastAPI版本〉= 0.93.0

您应该使用FastAPI应用程序的lifetime参数定义启动逻辑。更全面的文档可以在here中找到,我只展示一个最小的示例:

from contextlib import asynccontextmanager

from fastapi import FastAPI

def fake_answer_to_everything_ml_model(x: float):
    return True

ml_models = {}

@asynccontextmanager
async def lifespan(app: FastAPI):
    # Load your ML model
    ml_models["answer_to_everything"] = fake_answer_to_everything_ml_model
    yield
    # If you want you can define your shutdown logic after the `yield` keyword.

app = FastAPI(lifespan=lifespan)

相关问题