跳到主要内容

后台任务

前言

有时后端处理比较慢,但不需要前端等待任务完成再响应,比如发送短信/邮件、异步日志处理、大数据处理等。FastAPI 提供了 BackgroundTasks 后台任务机制:接口先返回响应,任务在响应发送后执行。

import time

from fastapi import BackgroundTasks


def send_mail(n: int):
time.sleep(n)
print("邮件已发送")


@router.get("/background", summary="后台任务, 模拟发送邮件")
async def back_send_mail(tasks: BackgroundTasks):
tasks.add_task(send_mail, 5)
return {"msg": "发送邮件的后台任务已添加"}

说明

  • 官方推荐从 fastapi 导入 BackgroundTasksfrom fastapi import BackgroundTasks);starlette.background.BackgroundTasks 是同一对象,也可以用。
  • add_task(func, *args, **kwargs) 支持同步和异步函数;同步函数在线程池中执行。
  • 任务在响应发送之后运行,任务抛出的异常不会影响已返回的响应,也不会被全局异常处理器捕获,需要自己在任务函数内处理异常并记录日志。
  • 后台任务适合短小、非关键的任务;长时间运行、需要重试/持久化的任务建议使用任务队列(Celery、TaskIQ)或独立调度器,见 补充:执行异步定时任务-基于DB的分布式锁
  • 后台任务在请求结束后,不再共享请求上下文(如 Request 对象),需要的数据应在 add_task 时作为参数显式传入;contextvars 的传递问题见 补充:TrackingID 的设计