问题描述
我正在使用由Uvicorn服务器提供服务的FastAPI框架.我的应用程序应在给定的端点(/运行)上运行一些耗时的数值计算.为此,我使用来自fastAPI的"background_task"(基本上是Starlette的"background_task").
I'm working with FastAPI framework, served by Uvicorn server.My application should run some time consuming numerical computation at a given endpoint (/run). For this I am using 'background_task' from fastAPI (which is basically 'background_task' from Starlette).
在运行应用程序时,经过一些正常的行为后,由于某种原因服务器被关闭.
When running the application, after some times of nominal behaviour, the server is shut down for some reason.
应用程序中的日志如下:
The logs from the application look like this:
INFO: Started server process [922]
INFO: Waiting for application startup.
DEBUG: None - ASGI [1] Started
DEBUG: None - ASGI [1] Sent {'type': 'lifespan.startup'}
DEBUG: None - ASGI [1] Received {'type': 'lifespan.startup.complete'}
INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
DEBUG: ('10.0.2.111', 57396) - Connected
DEBUG: ('10.0.2.111', 57397) - Connected
DEBUG: ('10.0.2.111', 57396) - ASGI [2] Started
DEBUG: ('10.0.2.111', 57396) - ASGI [2] Received {'type': 'http.response.start', 'status': 200, 'headers': '<...>'}
INFO: ('10.0.2.111', 57396) - "GET /run HTTP/1.1" 200
DEBUG: ('10.0.2.111', 57396) - ASGI [2] Received {'type': 'http.response.body', 'body': '<32 bytes>'}
DEBUG: ('10.0.2.111', 57396) - ASGI [3] Started
DEBUG: ('10.0.2.111', 57396) - ASGI [3] Received {'type': 'http.response.start', 'status': 404, 'headers': '<...>'}
INFO: ('10.0.2.111', 57396) - "GET /favicon.ico HTTP/1.1" 404
DEBUG: ('10.0.2.111', 57396) - ASGI [3] Received {'type': 'http.response.body', 'body': '<22 bytes>'}
DEBUG: ('10.0.2.111', 57396) - ASGI [3] Completed
...
DEBUG: ('10.0.2.111', 57396) - Disconnected
... The background task is completed.
DEBUG: ('10.0.2.111', 57396) - ASGI [2] Completed
DEBUG: ('10.0.2.111', 57397) - Disconnected
DEBUG: ('10.0.2.111', 57405) - Connected
...
The application goes on, with requests and completed background tasks.
At some point, during the execution of a background task:
INFO: Shutting down
DEBUG: ('10.0.2.111', 57568) - Disconnected
DEBUG: ('10.0.2.111', 57567) - Disconnected
INFO: Waiting for background tasks to complete. (CTRL+C to force quit)
DEBUG: ('10.0.2.111', 57567) - ASGI [6] Completed
INFO: Waiting for application shutdown.
DEBUG: None - ASGI [1] Sent {'type': 'lifespan.shutdown'}
DEBUG: None - ASGI [1] Received {'type': 'lifespan.shutdown.complete'}
DEBUG: None - ASGI [1] Completed
INFO: Finished server process [922]
我真的不明白为什么会这样.我不知道该如何解决该问题.
I really don't get why this happens. I have no idea what to try in order to fix it.
我的代码如下.
#!/usr/bin/env python3.7
import time
from fastapi import FastAPI, BackgroundTasks
import uvicorn
from starlette.responses import JSONResponse
import my_imports_from_project
analysis_api = FastAPI()
@analysis_api.get("/")
def root():
return {"message": "root"}
@analysis_api.get("/test")
def test():
return {"message": "test"}
@analysis_api.get("/run")
def run(name: str, background_task: BackgroundTasks):
try:
some_checks(name)
except RaisedExceptions:
body = {"running": False,
"name": name,
"cause": "Not found in database"}
return JSONResponse(status_code=400, content=body)
body = {"running": True,
"name": name}
background_task.add_task(run_analysis, name)
return JSONResponse(status_code=200, content=body)
if __name__ == "__main__":
uvicorn.run("api:analysis_api", host="0.0.0.0", log_level="debug")
推荐答案
这就是我解决整个问题的方法.
This is how I solved the whole problem.
我认为问题在于我的任务产生了一些进程以执行计算.因此,我现在使用的是 multiprocessing.Process()
,而不是使用FastApi的 background_task
.解决了.
I think that the problem was that my tasks spawn some processes in order to perform computations.So, instead of using FastApi background_task
, I am now using multiprocessing.Process()
.This solves it.
正如FastApi的专家指出的那样,如果项目变得庞大和复杂,此解决方案可能无法很好地扩展.在那种情况下,强烈建议使用消息队列+运行任务(如 FastApi网站.
As pointed out from the guys from FastApi, this solution might not scale well if the project becomes big and complex. In that case it is highly suggested to use something like a message queue + task running (as suggested on FastApi site.
但是,对于小型项目,使用 multiprocessing.Process
或 subprocess.Popen
的解决方案是完全可以的.
However, for small projects the solution with multiprocessing.Process
or subprocess.Popen
is totally fine.
这篇关于Uvicorn服务器意外关闭的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!