扫描二维码关注或者微信搜一搜:编程智域 前端至全栈交流与成长

发现1000+提升效率与开发的AI工具和实用程序https://tools.cmdragon.cn/

(一)BackgroundTasks 基本用法

1.1 任务处理机制

通过 FastAPI 的 BackgroundTasks 类型,我们可以将非即时性操作(如发送邮件、日志记录等)从主请求处理流程中分离。系统架构原理如下:

请求处理流程:

graph TD
A[客户端请求] --> B[FastAPI主线程]
B --> C{即时操作?}
C -->|是| D[同步处理并返回响应]
C -->|否| E[添加至BackgroundTasks队列]
E --> F[后台Worker异步处理]
F --> G[邮件/日志等非即时操作]

这种机制的优势在于:

  • 响应时间减少 40%-60%(根据任务复杂度)
  • 支持同步/异步混合任务处理
  • 自动处理任务依赖关系

1.2 基础实现步骤

使用 pydantic2.5.2 和 fastapi0.104.0 的示例:

from fastapi import BackgroundTasks, FastAPI
from pydantic import BaseModel app = FastAPI() # 定义数据模型
class UserRegistration(BaseModel):
username: str
email: str # 后台任务函数
def send_welcome_email(email: str):
# 模拟邮件发送(实际需替换真实SMTP配置)
print(f"Sending welcome email to {email}") # 路由处理
@app.post("/register")
async def create_user(
user: UserRegistration,
background_tasks: BackgroundTasks
):
# 添加后台任务
background_tasks.add_task(send_welcome_email, user.email)
return {"message": "Registration successful"}

关键实现要素:

  1. 注入 BackgroundTasks 参数到路由函数
  2. 通过 add_task 方法添加任务
  3. 任务函数支持同步/异步定义

(二)高级功能实现

2.1 依赖注入增强

结合依赖注入系统实现复用:

from typing import Annotated
from fastapi import Depends def get_notification_service():
# 模拟通知服务初始化
return NotificationService() @app.post("/order")
async def create_order(
background_tasks: BackgroundTasks,
notify_service: Annotated[NotificationService, Depends(get_notification_service)]
):
background_tasks.add_task(
notify_service.send_order_confirmation,
order_id=123
)

2.2 混合任务处理

同步与异步任务混合示例:

async def async_task_1():
await asyncio.sleep(1) def sync_task_2():
time.sleep(2) @app.get("/complex-task")
def complex_operation(background_tasks: BackgroundTasks):
background_tasks.add_task(async_task_1)
background_tasks.add_task(sync_task_2)

(三)测试与调试

3.1 单元测试示例

使用 pytest7.4.0 和 httpx0.25.0:

from fastapi.testclient import TestClient

def test_background_task():
client = TestClient(app) with mock.patch("module.send_welcome_email") as mock_task:
response = client.post("/register", json={
"username": "testuser",
"email": "test@example.com"
}) assert response.status_code == 200
mock_task.assert_called_once_with("test@example.com")

3.2 集成测试要点

  • 使用 --reload 参数检测任务执行
  • 通过日志监控任务状态
  • 使用任务队列中间件(如 Celery)进行扩展

课后 Quiz

Q1:当需要确保后台任务在应用关闭前完成时,应该如何处理?

A:使用 lifespan 事件监听,在 shutdown 阶段等待任务完成。正确做法是注册应用生命周期钩子,在关闭时调用 BackgroundTasks 的等待方法。

Q2:后台任务中出现异常会导致主请求失败吗?

A:不会。后台任务异常会记录到日志但不会影响主请求响应,需要通过自定义错误处理中间件捕获。

常见报错处理

报错现象:后台任务未执行

原因分析:

  1. 路由函数未正确注入 BackgroundTasks 参数
  2. 任务函数存在未处理的异常
  3. 应用未正确配置异步支持

解决方案:

  1. 检查路由参数声明顺序
  2. 添加任务日志记录
  3. 使用 try/except 包裹任务代码
  4. 确认是否启用 ASGI 服务器(如 uvicorn)

余下文章内容请点击跳转至 个人博客页面 或者 扫码关注或者微信搜一搜:编程智域 前端至全栈交流与成长,阅读完整的文章:如何在FastAPI中让后台任务既高效又不会让你的应用崩溃?

往期文章归档:

免费好用的热门在线工具

如何在FastAPI中让后台任务既高效又不会让你的应用崩溃?的更多相关文章

  1. 如何在MySQL中查询每个分组的前几名【转】

    问题 在工作中常会遇到将数据分组排序的问题,如在考试成绩中,找出每个班级的前五名等. 在orcale等数据库中可以使用partition语句来解决,但在mysql中就比较麻烦了.这次翻译的文章就是专门 ...

  2. 如何在Word中排出漂亮的代码

    引言 学数学和计算机,当然还是用LaTeX排版技术文章更方便.但有时候还是迫不得已需要用Word写作,另外Word其实也有Word的好处,比如细节上的修改要比LaTeX方便. 从Matlab高亮代码复 ...

  3. 为何在查询中索引未被使用 (Doc ID 1549181.1)

        To Bottom * 为何在查询中索引未被使用 (Doc ID 1549181.1) To Bottom 文档内容 用途   排错步骤   高速检查   表上是否存在索引?   索引是否应该 ...

  4. 【神经网络与深度学习】如何在Caffe中配置每一个层的结构

    如何在Caffe中配置每一个层的结构 最近刚在电脑上装好Caffe,由于神经网络中有不同的层结构,不同类型的层又有不同的参数,所有就根据Caffe官网的说明文档做了一个简单的总结. 1. Vision ...

  5. 如何在CMDB中落地应用的概念?

    如何在CMDB中落地应用的概念? 我们前面讲了应用是整个微服务架构体系下运维的核心,而CMDB又是整个运维平台的基石.今天我就讲讲在CMDB中如何落地应用这个核心概念,以及如何建立应用集群分组的思路. ...

  6. 关于如何在C#中调用C++的DLL,以及如何在C++中调用C#的DLL

    一.关于如何在C#中调用C++的DLL,以及如何在C++中调用C#的DLL 注:clr指公共语言运行库 CLR是一门非常恶搞的语言,就好像是在C++里面写C#的文件一样,也就是一种所谓的"托 ...

  7. 我是如何在SQLServer中处理每天四亿三千万记录的

    首先声明,我只是个程序员,不是专业的DBA,以下这篇文章是从一个问题的解决过程去写的,而不是一开始就给大家一个正确的结果,如果文中有不对的地方,请各位数据库大牛给予指正,以便我能够更好的处理此次业务. ...

  8. 【Win 10 应用开发】在App所在的进程中执行后台任务

    在以往版本中,后台任务都是以独立的专用进程来运行,因此,定义后台任务代码的类型都要位于 Windows 运行时组件项目中. 不过,在14393中,SDK 作了相应的扩展,不仅支持以前的独立进程中运行后 ...

  9. 如何在SpringBoot中使用JSP ?但强烈不推荐,果断改Themeleaf吧

    做WEB项目,一定都用过JSP这个大牌.Spring MVC里面也可以很方便的将JSP与一个View关联起来,使用还是非常方便的.当你从一个传统的Spring MVC项目转入一个Spring Boot ...

  10. 如何在latex 中插入EPS格式图片

    如何在latex 中插入EPS格式图片 第一步:生成.eps格式的图片 1.利用visio画图,另存为pdf格式的图片 利用Adobe Acrobat裁边,使图片大小合适 另存为.eps格式,如下图所 ...

随机推荐

  1. WPF中Resx文件中添加Byte[]

    参考:https://learn.microsoft.com/zh-tw/dotnet/api/system.resources.resxresourcewriter.generate?view=wi ...

  2. CsvHelper简单使用

    发现一个比较好用的处理csv的C#库,CsvHelper: CsvHelper是一个用于读取和写入CSV文件的C#库,支持自动类型转换.自定义类型转换器和灵活的映射选项等功能,使得读写CSV文件变得非 ...

  3. 设置IntelliJ IDEA 2021字体大小

      安装Mac版 IntelliJ IDEA 2021.3.1 (Ultimate Edition)后,就需要更改字体.IntelliJ IDEA的字体设置分为两部分:一部分是UI的字体和字号设置,另 ...

  4. Mysql数据类型TINYINT(1)与布尔型的坑

       需求背景:从MySQL数据库读取1.2.3.4等阿拉伯数字定义的状态,并转换成Java中Integer类型的数据,但是转换失败了.    问题分析:布尔型 bool 或者 boolean 在My ...

  5. Spring Boot 集成Mybatis和Druid快速入门

    MyBatis 是一个可以自定义SQL.存储过程和高级映射的持久层框架,它摒除了大部分的JDBC代码.手工设置参数和结果集重获,只使用简单的XML 和注解来配置和映射基本数据类型.Map 接口和POJ ...

  6. 化学数据分析AI实验室?ChatMoney帮你打造

    本文由 ChatMoney团队出品 AI确实是个好东西,但AI到底是有什么用?其实很多人都没搞明白.AI如果在某个行业用的好,是能带来很大经济价值的.就拿AI在化学应用来说,AI在化工领域上的应用和化 ...

  7. [GESP样题 七级] 最长不下降子序列题解

    题目传送门 题目大意 给定一个有向图无环图\(G\),在这个图中寻找一条路径,是这条路径上的点权所组成的序列的最长不下降子序列的长度最长. 思路部分 解决无后效性 求一个有向无环图中的最长不下降子序列 ...

  8. Coze工作流实战:一键生成像素风格视频

    前言 最近像素画风的视频非常火,一个视频浏览量超过10w+的也有很多. 那么这个是怎么实现的? 其实,通过AI工作流可以比较简单地实现这样的短视频. 今天给大家分享一下,我是如何搭建工作流实现的. 欢 ...

  9. 从数组和List中随机抽取若干不重复的元素

    一.从数组中随机抽取若干不重复元素 /** * @function:从数组中随机抽取若干不重复元素 * * @param paramArray:被抽取数组 * @param count:抽取元素的个数 ...

  10. Golang基础笔记一之变量声明和类型介绍

    本文首发于公众号:Hunter后端 原文链接:Golang基础笔记一之变量声明和类型介绍 这一篇笔记主要介绍 Golang 的基础内容,包括 Golang 的运行,变量声明以及 Golang 里的各种 ...