FastAPI BackgroundTasks 极简学习手册
FastAPI BackgroundTasks 极简学习手册
一、一句话搞懂BackgroundTasks
BackgroundTasks就是:用户请求后先快速返回结果,然后在后台悄悄完成那些不着急的工作。
就像你在奶茶店点单,服务员先给你一个取餐号(快速响应),然后再慢慢给你做奶茶(后台任务)。
二、适用场景(什么时候用)
✅ 适合做的事情:
- 发邮件(用户不需要等邮件发完才能看到注册成功)
- 写日志(用户不需要等日志写完就能继续操作)
- 处理数据(上传文件后立即返回,后台慢慢转码)
- 清理临时文件(用户下载完文件后,后台删除临时文件)
❌ 不适合做的事情:
- 支付处理(需要实时确认结果的关键任务)
- 大型数据计算(耗时太长会占用服务器资源)
三、核心区别:阻塞 vs 非阻塞
| 类型 | 通俗理解 | 像什么场景 | 执行时间 |
|---|---|---|---|
| 阻塞执行 | 排队一个一个做 | 食堂打饭,一个人打完下一个才能打 | 总时间=所有任务时间相加 |
| 非阻塞执行 | 同时做多个任务 | 手机后台同时下载多个App | 总时间=最慢的那个任务时间 |
1. 阻塞执行(默认方式)
用普通函数 def 定义任务,任务会按顺序执行,前一个任务做完才能做下一个。
1 | from fastapi import FastAPI, BackgroundTasks |
执行结果:先做拿铁(2秒),再做美式(2秒),总耗时4秒。
2. 非阻塞执行(并发方式)
用异步函数 async def 定义任务,配合 asyncio.create_task() 实现多个任务同时执行。
1 | from fastapi import FastAPI, BackgroundTasks |
执行结果:电影和音乐同时开始下载,总耗时3秒(和最慢的任务时间一样)。
3. CPU密集型任务处理(避免阻塞主线程)
对于像大量计算这样的CPU密集型任务,建议放到线程池中执行,避免影响服务器响应速度。
1 | from fastapi import FastAPI, BackgroundTasks |
四、关键注意事项(避坑指南)
异步函数不能直接用:不能直接把
async def函数传给add_task(),需要用asyncio.create_task()包装一下。任务超时问题:BackgroundTasks适合做轻量级任务(通常<3秒),超过5秒的任务建议用Celery等专业工具。
异常不会影响主线程:后台任务执行失败不会影响用户请求,但也不会通知你,所以最好在任务内部自己处理异常和记录日志。
不要依赖请求资源:后台任务不能直接访问已关闭的数据库连接或请求上下文,要自己管理需要的资源。
五、最佳实践总结
小任务用BackgroundTasks:比如发邮件、写日志这种轻量级任务,直接用BackgroundTasks就好。
大任务用专业工具:长时间运行的任务(如大型数据处理),用Celery+Redis/RabbitMQ组合。
拆分任务:把一个大任务拆成多个小任务,提高执行效率和可维护性。
加日志:在后台任务中添加详细的日志,方便出问题时排查。
六、快速记忆口诀
- 先返回,后做事:用户请求先给结果,后台再干活
- 轻任务,随便用:小活直接上BackgroundTasks
- 重任务,换工具:大活要用Celery专业队
- 阻塞排队,非阻塞并发:任务执行方式看需求
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 Nosaw博客!
评论




