FastAPI的BackgroundTasks如何玩转生产者-消费者模式?

1. BackgroundTasks 底层实现

FastAPI 的 BackgroundTasks 基于 Starlette 的 background task 实现,采用同步执行机制。当请求处理完成后,框架会顺序执行注册的后台任务。这种设计保证了:

  • 任务执行与响应返回的时序性
  • 异常任务的隔离处理
  • 请求上下文的安全访问
python 复制代码
from fastapi import BackgroundTasks, FastAPI

app = FastAPI()

def log_operation(operation: str):
    with open("audit.log", "a") as f:
        f.write(f"{datetime.now()} - {operation}\n")

@app.post("/transactions")
async def create_transaction(
    task: TransactionSchema,
    background_tasks: BackgroundTasks
):
    background_tasks.add_task(log_operation, f"New transaction {task.id}")
    return {"status": "processing"}

2. 生产者-消费者模式演进

当系统面临以下场景时需升级架构:

  • 单节点任务处理能力达到瓶颈
  • 需要保证任务执行的顺序性
  • 要求任务执行结果的可追溯性
graph TD A[客户端请求] --> B[API 接收请求] B --> C{立即响应} C --> D[生产者存入队列] D --> E[Redis/RabbitMQ] E --> F[消费者读取任务] F --> G[任务处理模块] G --> H[结果持久化]

分布式任务处理实现

1. 架构组件配置

python 复制代码
# requirements.txt
celery==5.3.0
pydantic==1.10.7
redis==4.5.5

2. 生产者服务实现

python 复制代码
from celery import Celery
from pydantic import BaseModel

class TaskPayload(BaseModel):
    user_id: int
    content: str
    priority: int = 1

celery_app = Celery('worker', broker='redis://localhost:6379/0')

@app.post("/tasks")
async def create_task(
    payload: TaskPayload,
    background_tasks: BackgroundTasks
):
    background_tasks.add_task(
        celery_app.send_task,
        'process_task',
        kwargs=payload.dict()
    )
    return {"task_id": str(uuid.uuid4())}

3. 消费者服务实现

python 复制代码
@celery_app.task(name='process_task')
def process_task(user_id: int, content: str, priority: int):
    try:
        result = ContentProcessor().analyze(content)
        TaskResult.objects.create(
            user_id=user_id,
            content=content,
            result=result
        )
        return {"status": "success"}
    except AnalysisError as e:
        logger.error(f"Processing failed: {str(e)}")
        raise self.retry(exc=e, countdown=30)

异常处理机制

python 复制代码
@app.exception_handler(CeleryError)
async def celery_error_handler(request: Request, exc: CeleryError):
    return JSONResponse(
        status_code=503,
        content={"message": "Task system temporarily unavailable"}
    )

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

课后 Quiz

问题 1 :当使用 Redis 作为消息代理时,如何保证任务不丢失? 答案解析

  1. 启用 Redis 持久化配置 (AOF + RDB)
  2. 设置任务确认机制 (acks_late=True)
  3. 实现死信队列处理机制

问题 2 :如何实现任务优先级处理? 答案解析

  1. 在 Celery 配置中设置 task_routes
  2. 使用不同队列对应不同优先级
  3. 消费者启动时指定优先级参数:
bash 复制代码
celery -A worker worker -Q high_prio,low_prio -c 4

常见报错处理

错误现象TaskRevokedError: Task revoked before execution

解决方案

  1. 检查 Celery 的 worker 日志确认终止原因
  2. 增加任务超时配置:
python 复制代码
@celery_app.task(bind=True, soft_time_limit=60)
def process_task(self):
    ...
  1. 实现任务状态追踪中间件

预防建议

  1. 监控系统内存使用情况
  2. 设置合理的任务超时阈值
  3. 使用任务进度上报机制
相关推荐
鬼火儿18 小时前
SpringBoot】Spring Boot 项目的打包配置
java·后端
cr7xin18 小时前
缓存三大问题及解决方案
redis·后端·缓存
赵文宇(温玉)19 小时前
构建内网离线的“github.com“,完美解决内网Go开发依赖
开发语言·golang·github
间彧19 小时前
Kubernetes的Pod与Docker Compose中的服务在概念上有何异同?
后端
间彧19 小时前
从开发到生产,如何将Docker Compose项目平滑迁移到Kubernetes?
后端
牛奶咖啡1319 小时前
利用Github与Hexo搭建属于自己的在线个人博客
github·hexo创建静态博客·免费部署博客到公网上·创建自定义静态博客·将静态博客上传到github·将自己的网站发布到网上
散峰而望19 小时前
C++入门(一)(算法竞赛)
c语言·开发语言·c++·编辑器·github
间彧19 小时前
如何结合CI/CD流水线自动选择正确的Docker Compose配置?
后端
间彧19 小时前
在多环境(开发、测试、生产)下,如何管理不同的Docker Compose配置?
后端
间彧19 小时前
如何为Docker Compose中的服务配置健康检查,确保服务真正可用?
后端