FastAPI 如何触发 FastAPI/Uvicorn 的优雅停机

FastAPI 如何触发 FastAPI/Uvicorn 的优雅停机

在本文中,我们将介绍如何触发 FastAPI/Uvicorn 的优雅停机。当我们需要停止 FastAPI 应用程序时,我们希望尽可能地保证应用程序可以正常关闭,并且处理完当前正在处理的请求。

阅读更多:FastAPI 教程

1. 关闭 FastAPI 和 Uvicorn 服务器

为了实现优雅停机,我们首先需要关闭 FastAPI 和 Uvicorn 服务器。我们可以使用以下方式来完成:

import uvicorn
from fastapi import FastAPI

app = FastAPI()

@app.get("/")
def read_root():
    return {"Hello": "World"}

if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=8000)

当我们使用 ctrl+C 停止运行时,FastAPI 和 Uvicorn 服务器将会立即停止,但这没有给予它们完成当前处理的请求的机会。为了实现优雅停机,我们可以使用 uvicorn.Server 类来创建服务器实例,并使用 Server.install_signal_handlers() 方法来安装信号处理程序。

下面是一个示例:

import signal
import uvicorn
from fastapi import FastAPI

app = FastAPI()
server = uvicorn.Server(uvicorn.Config(app))

@app.on_event("shutdown")
async def shutdown():
    server.should_exit = True

@app.get("/")
def read_root():
    return {"Hello": "World"}

if __name__ == "__main__":
    server.install_signal_handlers()
    uvicorn.run(app, host="0.0.0.0", port=8000)

在上面的示例中,我们使用 @app.on_event("shutdown") 装饰器来定义一个异步函数 shutdown(),并在函数中设置服务器实例的 should_exit 属性为 True。这样,当我们停止运行应用程序时,服务器实例将会收到一个信号来优雅地停止。

2. 处理当前请求

在上述示例中,我们设置了服务器实例的 should_exit 属性为 True,但这并没有立即停止服务器,只是发送了一个信号告知服务器应该停止。为了让服务器能够处理完当前正在处理的请求,我们可以使用协程来延迟停机。

下面是一个示例:

import asyncio
import signal
import uvicorn
from fastapi import FastAPI

app = FastAPI()
server = uvicorn.Server(uvicorn.Config(app))

@app.on_event("shutdown")
async def shutdown():
    server.should_exit = True
    await asyncio.sleep(3)

@app.get("/")
def read_root():
    return {"Hello": "World"}

if __name__ == "__main__":
    server.install_signal_handlers()
    uvicorn.run(app, host="0.0.0.0", port=8000)

在上述示例中,我们在 shutdown() 函数中使用了 asyncio.sleep(3) 来延迟停机3秒钟,以确保当前处理的请求可以完成。你可以根据应用程序的实际情况来调整延迟的时间。

3. 优雅停机的重试策略

在某些情况下,应用程序可能无法在规定的时间内完成当前的处理。为了提高可靠性,我们可以实现一个重试策略,在超过一定时间后强制停止服务器。

下面是一个示例:

import asyncio
import signal
import uvicorn
from fastapi import FastAPI

app = FastAPI()
server = uvicorn.Server(uvicorn.Config(app))

SHUTDOWN_TIMEOUT = 10

@app.on_event("shutdown")
async def shutdown():
    server.should_exit = True
    await asyncio.sleep(3)

async def force_shutdown():
    await asyncio.sleep(SHUTDOWN_TIMEOUT)
    if not server.should_exit:
        server.force_exit = True

@app.get("/")
def read_root():
    return {"Hello": "World"}

if __name__ == "__main__":
    server.install_signal_handlers()
    asyncio.ensure_future(force_shutdown())
    uvicorn.run(app, host="0.0.0.0", port=8000)

在上述示例中,我们定义了一个异步函数 force_shutdown(),该函数在延迟了一定时间后,检查服务器实例的 should_exit 属性,如果服务器还未停止,则将其强制退出。

总结

在本文中,我们介绍了如何触发 FastAPI/Uvicorn 的优雅停机。通过设置服务器实例的属性,并使用协程来延迟和强制停机,我们可以实现应用程序的优雅关闭,确保处理完当前正在处理的请求。根据具体需求,我们还可以实现重试策略,提高可靠性。希望本文对你有所帮助!

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程