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. 使用任务进度上报机制
相关推荐
bobz9651 小时前
5070 Ti CodeLlama 7B > Mistral 7B > Qwen3 8B
后端
前端日常开发1 小时前
我用Trae写了个数字滚动器,结果看了一下午!
trae
麦兜*1 小时前
Spring Boot 集成 Docker 构建与发版完整指南
java·spring boot·后端·spring·docker·系统架构·springcloud
程序视点2 小时前
2025最佳图片无损放大工具推荐:realesrgan-gui评测与下载指南
前端·后端
fured3 小时前
[调试][实现][原理]用Golang实现建议断点调试器
开发语言·后端·golang
围巾哥萧尘4 小时前
烟花模拟器 Fireworks Simulator 🧣
trae
bobz9654 小时前
linux cpu CFS 调度器有使用 令牌桶么?
后端
bobz9654 小时前
linux CGROUP CPU 限制有使用令牌桶么?
后端
David爱编程5 小时前
多核 CPU 下的缓存一致性问题:隐藏的性能陷阱与解决方案
java·后端
围巾哥萧尘5 小时前
AI智能旅游规划 让每次旅行都完美无缺🧣
trae