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