在现代的 Web 开发中,后台任务处理是一个常见的需求。FastAPI 提供了一个非常方便的功能,名为 BackgroundTasks,它允许在处理请求后执行一些后台任务。这些任务对于不需要即时返回结果的操作非常有用,比如发送电子邮件、日志记录、数据缓存等。

BackgroundTasks 的基本使用

首先,看看如何在 FastAPI 中使用 BackgroundTasks

  1. 导入 BackgroundTasks
1
from fastapi import FastAPI, BackgroundTasks
  1. 定义后台任务函数
1
2
3
def some_background_task(arg1, arg2):
# 后台任务的代码
print(f"后台任务执行,参数:{arg1}, {arg2}")
  1. 在路径操作函数中添加后台任务
1
2
3
4
5
6
app = FastAPI()

@app.post("/background_task/")
def background_task(background_tasks: BackgroundTasks):
background_tasks.add_task(some_background_task, "参数1", "参数2")
return {"message": "后台任务添加成功"}

在这个例子中,当客户端发送 POST 请求到 /background_task/ 路径时,some_background_task 函数将作为一个后台任务被添加,并在主函数执行完毕后开始运行。

BackgroundTasks 是并行的吗?

关于 BackgroundTasks 的并行性,这是一个常见的问题。答案是,BackgroundTasks 默认情况下是顺序执行的,而不是并行的。这意味着,即使你添加了多个后台任务,它们也会按照添加的顺序一个接一个地执行。

然而,如果你需要并行执行后台任务,FastAPI 也支持这一点。你可以通过定义异步的后台任务函数来实现。

使用异步后台任务实现并行执行

以下是如何使用异步后台任务的示例:

  1. 定义异步后台任务函数
1
2
3
4
async def some_background_task(arg1, arg2):
# 异步后台任务的代码
print(f"异步后台任务执行,参数:{arg1}, {arg2}")
await asyncio.sleep(1) # 模拟异步操作
  1. 在路径操作函数中添加异步后台任务
1
2
3
4
@app.post("/background_tasks_async/")
async def background_tasks_async(background_tasks: BackgroundTasks):
background_tasks.add_task(some_background_task, "参数1", "参数2")
return {"message": "异步后台任务添加成功"}

在这个例子中,some_background_task 是一个异步函数,它将被并行执行,前提是 FastAPI 应用是在支持异步的 ASGI 服务器上运行的(例如 Uvicorn)。

请注意,即使任务是异步的,它们仍然会在单个进程或线程中按顺序添加到事件循环中,由事件循环来调度它们的执行。这意味着,尽管任务可以并发运行,但它们并不是在多个 CPU 核心上真正并行执行的。

结论

FastAPI 的 BackgroundTasks 提供了一种简单而有效的方式来处理后台任务。虽然它默认是顺序执行的,但通过使用异步函数,可以实现任务的并行执行。这使得 FastAPI 成为构建高效、可扩展的 Web 应用的理想选择。