Django 6.0 自带 Tasks 能替代 Celery 吗?3 组实测后的结论与选型建议

阿澈
阿澈
发布时间:2026-08-23 | 168人浏览过
原创

前言

Django 6.0 把 Tasks 框架纳入核心后,很多团队都会追问同一个问题:既然已经有统一的任务接口,Celery 还有没有继续存在的必要。单看 API 很容易误判,所以这篇文章把 Django 6.0.7、Celery 5.6.3 和本机 Redis 放到同一组 1.5 秒任务里实测,再结合接口设计和执行链路,拆清楚“能统一调用”和“能稳定跑生产后台任务”之间到底差了什么。

Django 6.0 把 Tasks 框架正式纳入核心后,很多开发者第一反应都是:既然已经有 @task、enqueue()、队列名、优先级和结果对象,项目里是不是终于可以不再接 Celery 了?这个问题不能只看发布说明,因为“有统一接口”和“能在生产环境稳定跑后台任务”根本不是一回事。

为了把边界看清楚,本文按同一组 1.5 秒耗时任务分别测试了三种方案:普通同步函数、Django 自带 ImmediateBackend/DummyBackend,以及 Redis + 独立 Celery Worker。看完你可以直接判断:Django Tasks 到底解决了什么、没解决什么,以及新老项目该怎么选型。

Django 6.0 到底内置了什么

Django 官方对 Tasks 的定位非常克制:它提供的是后台工作的“contract and plumbing”,也就是任务契约和连接管道,真正负责搬运、调度和执行任务的引擎,仍然交给外部基础设施。

一个最小任务可以这样定义:

from django.tasks import task

@task
def generate_report(report_id):
    # 生成报表
    return {"report_id": report_id, "status": "done"}

调用方式也不是 Celery 常见的 delay(),而是 Django 自己的 enqueue():

result = generate_report.enqueue(42)

这套 API 还统一了几类关键概念:

  • priority:任务优先级
  • queue_name:目标队列
  • backend:使用哪个任务后端
  • run_after:最早执行时间
  • TaskResult:任务状态、尝试次数、错误与返回值
  • enqueue() / aenqueue():同步与异步提交接口

这件事本身很有价值。过去每个任务库都有自己的装饰器、调用方式和结果对象;从 Django 6.0 开始,业务代码至少可以先围绕统一接口组织,再把具体执行能力交给后端实现。

但要注意,统一接口并不等于任务已经被真正移出 Web 请求进程。

两个内置 Backend 为什么都不能当生产 Worker

Django 6.0 自带了两个后端,但它们都不等于“生产可用的后台任务系统”。

ImmediateBackend:调用了 enqueue,任务还是在当前进程执行

默认配置就是 ImmediateBackend:

TASKS = {
    "default": {
        "BACKEND": "django.tasks.backends.immediate.ImmediateBackend",
    }
}

它的行为很直接:调用 enqueue() 时立即执行任务函数。如果任务要跑 1.5 秒,请求就照样等待 1.5 秒,和真正的异步执行不是一回事。

它更适合这些场景:

  • 本地开发时先把业务调用改成 Tasks API
  • 单元测试中验证任务逻辑
  • 在正式队列设施尚未接入前,先完成接口迁移

它并不能把耗时工作移出 Web 进程。

DummyBackend:返回很快,但它根本不执行任务

DummyBackend 的配置如下:

TASKS = {
    "default": {
        "BACKEND": "django.tasks.backends.dummy.DummyBackend",
    }
}

它会记录入队行为,方便测试断言,但不会真正执行任务函数。所以如果它在 1 ms 内返回,并不能说明“Django 后台任务性能很强”,只能说明它只做了记录,任务状态会停留在 READY。

官方文档写得很明确:Django 内置的只是开发和测试后端,生产可用后端需要额外配置。

测试环境、执行步骤与五轮结果

为了把差异跑实,测试环境固定如下:

项目配置
Python3.12
Django6.0.7
Celery5.6.3
BrokerRedis,本地独立数据库编号
Worker单独进程,--pool=solo
任务内容sleep(1.5),模拟邮件、报表或文件处理
轮数5 轮

测试任务会返回执行进程 PID,用来确认它到底是仍在请求进程里运行,还是已经被独立 Worker 接走。

第一组:普通同步函数

def slow_job(delay_seconds):
    time.sleep(delay_seconds)
    return {"worker_pid": os.getpid()}

这一组没什么悬念:直接调用时,请求进程必须完整等待任务结束。

第二组:Django ImmediateBackend 与 DummyBackend

from django.tasks import task

@task
def django_slow_job(delay_seconds):
    return slow_job(delay_seconds)

immediate_result = django_slow_job.enqueue(1.5)
dummy_result = django_slow_job.using(backend="dummy").enqueue(1.5)

这里的关键区别只有一句话:ImmediateBackend 会真的执行,DummyBackend 只做记录。

第三组:Redis + 独立 Celery Worker

Celery 任务定义如下:

from celery import Celery

app = Celery(
    "django_tasks_demo",
    broker="redis://127.0.0.1:6379/13",
    backend="redis://127.0.0.1:6379/14",
)

@app.task
def celery_slow_job(delay_seconds):
    time.sleep(delay_seconds)
    return {"worker_pid": os.getpid()}

启动独立 Worker:

python -m celery -A celery_app:app worker `
  --pool=solo `
  --queues=ruyi_django_tasks_demo

提交任务并记录入队耗时:

started = time.perf_counter()
result = celery_slow_job.delay(1.5)
enqueue_ms = (time.perf_counter() - started) * 1000

实验里调用 result.get(),只是为了确认 Worker 最终确实执行完成并统计完整耗时。真实 Web 请求里通常不应该在提交后立刻 get(),否则异步流程又会被你自己等回同步。

五轮结果说明了什么

方案平均返回时间最小值最大值是否执行执行进程
同步函数1500.29 ms1500.18 ms1500.54 ms是请求进程 PID 42268
Django ImmediateBackend1500.66 ms1500.39 ms1501.24 ms是请求进程 PID 42268
Django DummyBackend0.31 ms0.16 ms0.84 ms否无
Celery 入队返回13.66 ms0.68 ms65.18 ms是Worker PID 37412

Celery 任务的平均完整完成时间是 1515.71 ms。任务本身并没有被“加速”,仍然需要大约 1.5 秒;真正变化的是,请求线程只负责把消息送进队列,实际执行改由另一个进程承担。

这正是后台任务最核心的价值:不是让工作凭空更快,而是让 Web 请求不用陪着耗时任务一起阻塞。

还有一个细节值得单独看待:Celery 首轮入队时间偏高,主要来自首次建立 Broker 连接的成本,后续轮次最低降到了 0.68 ms。所以单次冷启动结果不能直接代表长期吞吐,更不能拿本机样本直接当作生产性能承诺。

Django Tasks 和 Celery 的能力边界,到底差在哪

能力Django 6.0 Tasks 核心Celery
统一任务声明与入队接口是有自己的 API
自带生产 Worker否是
自带生产消息传输否支持 Redis、RabbitMQ 等 Broker
重试、路由、并发控制取决于外部 Backend成熟支持
定时与复杂工作流取决于外部 BackendCelery Beat、Canvas 等生态
测试时立即执行或只记录内置支持可用 eager 等配置
结果监控与运维工具取决于 Backend有成熟生态

所以“Django Tasks 能不能替代 Celery”,最好拆成两个问题来看:

概括 Django Tasks 与 Celery 在接口、执行、重试和运维层面的能力边界
接口层与执行层的分工Django Tasks 解决的是统一接口,Celery 解决的是生产级搬运、执行和运维。
  1. 能不能替代 Celery 的业务调用接口?可以朝这个方向走。只要使用兼容的生产 Backend,业务层确实可以围绕 Django 的 @task 和 enqueue() 来写。
  2. 能不能替代 Celery 的队列、Worker、重试和运维体系?Django 核心本身做不到。

新项目和老项目,应该怎么选

适合优先采用 Django Tasks + 生产 Backend 的情况

  • 新建 Django 6.0 项目,希望先统一任务接口
  • 任务模型相对简单,以发邮件、生成缩略图、轻量数据处理为主
  • 已经验证某个外部 Backend 能满足延迟、优先级、结果查询和异步执行能力
  • 希望未来替换任务实现时,尽量少改业务层代码

选型时不要只看 Backend 能不能装上。Django Tasks 为后端预留了一组能力标志,比如 supports_defer、supports_priority、supports_get_result、supports_async_task,真正落地前最好逐项核实。

总结新项目与老项目在 Django Tasks、Celery 之间的选型条件与常见误区
项目选型与常见坑选型重点不在于新旧之争,而在于任务复杂度、现有基础设施和对重试、路由、事务时序的要求。

适合继续使用 Celery 的情况

  • 现有系统已经稳定运行在 Celery 之上
  • 需要任务重试、限流、路由、多队列、定时任务或复杂工作流
  • 需要多机部署或多类 Worker 分工
  • 已经有 Redis/RabbitMQ、监控和部署体系
  • 团队已经积累了 Celery 的运维和故障处理经验

仅仅因为 Django 6.0 新增了 Tasks,就把成熟 Celery 体系整体重写,通常没有现实收益。

三个最容易踩的坑

坑一:把 enqueue() 误认为一定异步

enqueue() 的真实执行方式由 Backend 决定。默认的 ImmediateBackend 仍然会阻塞当前调用者。

坑二:测试返回很快,就误判生产也没问题

DummyBackend 不执行任务,ImmediateBackend 不离开当前进程。两者都不能证明生产队列链路已经可用。

坑三:事务还没提交,Worker 已经开始读数据

比如创建订单后立刻投递邮件任务,Worker 可能先于数据库事务提交去读取订单。更稳妥的通用做法,是在事务提交成功后再入队:

from django.db import transaction

transaction.on_commit(lambda: generate_report.enqueue(report_id))

Celery 的 Django 集成也提供了 delay_on_commit() 来处理这个场景。任务参数最好传主键这类稳定标识,让 Worker 执行时重新读取最新数据,而不是直接序列化整个模型对象。

Windows 实验为什么只能说明链路,不等于生产建议

这次实验为了在本机完成可重复验证,Celery Worker 使用了 --pool=solo。Celery 官方目前并不承诺 Windows 支持,这个配置适合演示独立进程和消息队列链路,但不能直接等同于生产部署建议。

真正上线时,通常还是应该在 Linux 环境下,根据任务类型评估 Worker 并发模型,并配合正式维护的 Redis 或 RabbitMQ 服务使用。

结论:Django Tasks 统一了接口,但没替你实现后台执行系统

Django 6.0 Tasks 最重要的意义,不是“Django 把 Celery 做进核心了”,而是 Django 终于提供了一套框架级的任务语言:

  • 用 @task 声明任务
  • 用 enqueue() 提交任务
  • 用 Backend 隔离具体执行设施
  • 用统一的结果与能力模型描述任务状态

但协议不会自己执行任务。没有生产 Backend、Broker 和 Worker,耗时工作仍然不会真正离开请求进程。

结论可以说得很直白:Django Tasks 的价值,在于降低业务代码和具体任务库之间的耦合;但它并不是 Celery 的完整替代品。 对已经有复杂异步架构的项目,继续使用 Celery 仍然是更稳妥的选择;而对于新建的 Django 6.0 项目,优先采用 Tasks API,再谨慎挑选生产后端,才是更现实的路线。

参考资料

  • Django 6.0 Tasks API 官方文档
  • Django Tasks 使用指南
  • Celery 5.6 官方入门文档
  • Celery 与 Django 官方集成指南
  • Celery 并发模型文档

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表