一、Celery入门

介绍

Celery 是一个简单、灵活且可靠的分布式任务队列系统,专注于实时处理的异步任务队列,同时也支持任务调度。Celery是实现异步任务、定时任务的一种工具。

Celery 的核心功能

  • 异步任务处理:将耗时的任务异步执行,不阻塞主程序,从而提高系统的响应速度和扩展性。例如邮件发送、消息推送等。
  • 定时任务调度:可以按照预设的时间间隔或特定时间点执行任务,例如定时清理日志、定时统计数据等。
  • 分布式任务执行:支持在多台服务器上运行 worker 进程,扩展到分布式环境中。
  • 任务状态跟踪和结果存储:可以跟踪任务的执行状态,并将任务的执行结果存储。

Celery 的架构

  • 消息中间件 (Broker):负责接收任务生产者发送的消息并将任务存入队列。常用的消息中间件有 Redis 和 RabbitMQ
  • 任务执行单元 (Worker):执行任务的实际工作进程,会从消息队列中取出任务并执行 。
  • 任务结果存储 (Backend):用于存储任务执行结果,可以是 Redis、RabbitMQ 或数据库 。
  • 任务调度器 (Beat):用于调度定时任务,会周期性地将到期需要执行的任务发送给消息队列 。

Celery 的工作流程

  1. 任务生产者将任务发送到消息队列。
  2. 消息队列存储任务,直到任务消费者获取它们。
  3. 任务消费者从消息队列中获取任务,并在本地执行。
  4. 执行完成后,任务结果存储到结果存储后端。
  5. 任务生产者可以通过 AsyncResult 查询任务的状态和结果。

生产环境建议

  • Windows 平台上安装Celery,只能用于开发环境或测试环境。生产环境,建议使用 Linux 平台。

安装

安装Redis 作为消息中间件(过程略)

安装 Celery 和 Redis客户端

pip install redis
pip install celery

二、Celery与Django集成实战

配置Celery实例

Django项目结构示例

- mysite/
- manage.py
- mysite/
- __init__.py
- settings.py
- urls.py

定义 Celery 实例:创建文件mysite\mysite\celery.py

"""定义和配置 Celery 实例"""

import os
from celery import Celery
from django.conf import settings os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings")
# 创建 Celery 实例
app = Celery("mysite")
# 加载配置文件中的 Celery 配置
app.config_from_object("django.conf:settings", namespace="CELERY")
# 自动发现并加载任务
app.autodiscover_tasks(["myapp_infra", "myapp_system"] + settings.MY_APPS, force=True)

配置 Django 启动时会加载应用:修改文件mysite\mysite\__init__.py

"""Django 启动时加载Celery实例"""

from .celery import app as celery_app

__all__ = ("celery_app",)

配置Celery:修改Django项目文件settings.py

### Celery配置
CELERY_RESULT_BACKEND = "redis://localhost:6379/2"
CELERY_BROKER_URL = "redis://localhost:6379/3"
CELERY_TIMEZONE = "Asia/Shanghai"
CELERY_ENABLE_UTC = True
CELERY_RESULT_EXTENDED = True # 启用后才会记录 task_name、date_started 等字段
CELERY_TASK_TRACK_STARTED = True # 记录任务开始时间

定义任务

发现任务:Celery 将自动从所有已安装的应用APP中发现任务,需要遵守以下目录结构

- myapp_system/
- tasks.py
- models.py
- myapp_infra/
- tasks.py
- models.py

定义任务:创建文件myapp_infra/tasks.py,使用@shared_task装饰器定义 Celery 任务

"""定义 Celery 任务"""

from celery import shared_task
from time import sleep @shared_task
def send_email_task(subject, message, recipient_list):
"""
发送电子邮件的任务
"""
print("发送邮件任务开始执行...")
sleep(3)
print(f"主题: {subject}")
print(f"内容: {message}")
print(f"收件人: {recipient_list}")
print("#" * 10, "\n")

调用任务

调用任务:在视图或其他代码中,使用 .delay() 方法将任务发送到 Celery 队列中。

from rest_framework.views import APIView
from rest_framework.response import Response
from .tasks import send_email_task class SendEmailView(APIView):
def get(self, request):
subject = "Hello from Celery"
message = "This is a test email sent using Celery."
recipient_list = ["user@example.com"] # 异步发送邮件
send_email_task.delay(subject, message, recipient_list) return Response({"message": "Email sent successfully"})

启动

启动Celery工作进程:在开发和测试环境中,使用下面命令启动Celery工作进程

# 进入Django项目目录(包含manage.py的目录)
celery -A mysite worker -l INFO -P solo

启动Django项目

# 进入Django项目目录(包含manage.py的目录)
python manage.py runserver

实战效果

当访问SendEmailView 视图,会看到日志中显示任务已触发和执行。

[2025-04-14 09:11:53,151: INFO/MainProcess] Task mybooks.tasks.send_email_task[c37a8725-aa59-43b4-9949-74a753c019a2] received
[2025-04-14 09:11:55,185: WARNING/MainProcess] 发送邮件任务开始执行...
[2025-04-14 09:11:58,186: WARNING/MainProcess] 主题: Hello from Celery
[2025-04-14 09:11:58,186: WARNING/MainProcess] 内容: This is a test email sent using Celery.
[2025-04-14 09:11:58,186: WARNING/MainProcess] 收件人: ['user@example.com']
[2025-04-14 09:11:58,187: WARNING/MainProcess] ##########
[2025-04-14 09:11:58,187: WARNING/MainProcess]

三、delay_on_commit

使用场景

delay_on_commit 是 Celery 提供的一个用于确保任务在数据库事务提交后执行的机制。考虑以下场景:

  • send_email任务可能会在视图将事务提交到数据库之前启动,因此任务可能无法找到用户。
  • 如果事务回滚,任务仍然会执行,处理一个不存在或无效的订单。
# views.py
def create_user(request):
user = User.objects.create(username=request.POST['username'])
send_email.delay(user.pk)
return HttpResponse('User created') # task.py
@shared_task
def send_email(user_pk):
user = User.objects.get(pk=user_pk)
# send email ...

使用方法

delay_on_commit 会将任务调度延迟到当前事务成功提交后执行。如果事务回滚,任务也不会被调度。

# views.py
from django.db import transaction
from .tasks import send_email_task @transaction.atomic
def create_user(request):
user = User.objects.create(username="zhangsan") # 数据库操作 # 正确:事务提交后才会触发任务
send_email_task.delay_on_commit(user.id) # 如果此处抛出异常导致事务回滚,任务不会被执行
return HttpResponse("OK")

点击查看完整代码


您正在阅读的是《Django从入门到实战》专栏!关注不迷路~

Django 实战:Celery 异步任务从环境搭建到调用全掌握的更多相关文章

  1. [置顶] Django 微信开发(一)——环境搭建

    Django 微信开发(一)——环境搭建 随着移动互联网时代的到来,微信——一个改变着我们生活的产品悄悄走近了我们的生活.我们不得不觉得自己很幸运,自己能在这个世界上遇到像QQ.微博.微信这样优秀的产 ...

  2. django、celery异步发邮件

    django.celery异步发邮件 django自带的send_mail发邮件功能执行发邮件功能会因为网络的原因造成花费的时间过长,为了解决这个问题,可以用celery + redis代替 安装包: ...

  3. 环境篇:CM+CDH6.3.2环境搭建(全网最全)

    环境篇:CM+CDH6.3.2环境搭建(全网最全) 一 环境准备 1.1 三台虚拟机准备 Master( 32g内存 + 100g硬盘 + 4cpu + 每个cpu2核) 2台Slave( 12g内存 ...

  4. Django使用Celery异步任务队列

    1  Celery简介 Celery是异步任务队列,可以独立于主进程运行,在主进程退出后,也不影响队列中的任务执行. 任务执行异常退出,重新启动后,会继续执行队列中的其他任务,同时可以缓存停止期间接收 ...

  5. Java Web项目实战第1篇之环境搭建

    写在前面的话 从今天开始一个Java Web实战项目,参考自 http://blog.csdn.net/eson_15/article/details/51277324 这个博客(非常感谢博主的分享精 ...

  6. 从零开始react实战:云书签-1 react环境搭建

    总览篇:react 实战之云书签 本篇是实战系列的第一篇,主要是搭建 react 开发环境,在create-react-app的基础上加上如下功能: antd 组件库按需引入 ,支持主题定制 支持 l ...

  7. 《OD大数据实战》Hadoop伪分布式环境搭建

    一.安装并配置Linux 8. 使用当前root用户创建文件夹,并给/opt/下的所有文件夹及文件赋予775权限,修改用户组为当前用户 mkdir -p /opt/modules mkdir -p / ...

  8. Guns(开源后台管理系统框架)实战(一)——开发环境搭建

    1. 开发环境搭建 1.1. 开发环境要求 1.2. 配置Maven 1.3. 配置MySQL 1.4. Git克隆项目 1.5. Eclipse导入系统 2. 小结 3. 参考引用 1. 开发环境搭 ...

  9. 2- vue django restful framework 打造生鲜超市 -环境搭建

    使用Python3.6与Django2.0.2(Django-rest-framework)以及前端vue开发的前后端分离的商城网站 项目支持支付宝支付(暂不支持微信支付),支持手机短信验证码注册, ...

  10. kubernetes实战之consul简单测试环境搭建及填坑

    这一节内容有点长,我们将介绍如何基于docker搭建一client一server的consul测试环境,以及如何搭建多server consul测试集群.在基于docker搭建多server的cons ...

随机推荐

  1. DPDI(Dispatch PDI)kettle调度管理平台发布新版本了

    Dispatch PDI最新版本发布! 我们很高兴地宣布,Dispatch PDI的全新轻量级版本现已在官网上线!这款专为高效ETL任务调度和监控设计的平台,将为您的数据处理带来前所未有的便捷. 立即 ...

  2. hybrid应用自动化

    一.hybrid介绍 hybrid是一种混合app,将h5页面嵌入native原生页面. 基于uiautomator+chromedriver.native部分走uiautomator,web部分走c ...

  3. 通用型产品发布解决方案(基于分布式微服务技术栈:SpringBoot+SpringCloud+Spring CloudAlibaba+Vue+ElementUI+MyBatis-Plus+MySQL+Git+Maven+Linux+Docker+Nginx - 《01》

    通用型产品发布解决方案(基于分布式微服务技术栈:SpringBoot+SpringCloud+Spring CloudAlibaba+Vue+ElementUI+MyBatis-Plus+MySQL+ ...

  4. 备注一下,SolidColorBrush,自定义颜色

    new SolidColorBrush((Color)ColorConverter.ConvertFromString("#27212B"))

  5. swagger加权限

    参照: [Blog.Core开源]开发插件,给Swagger加权 - 腾讯云开发者社区-腾讯云 (tencent.com)

  6. EF Core Demo1——初识DbContext

    EF中的上下文(DbContext)简介   DbContext是实体类和数据库之间的桥梁,DbContext主要负责与数据交互,主要作用: 1.DbContext包含所有的实体映射到数据库表的实体集 ...

  7. 国际化利器 Intl Messageformat

    我们是袋鼠云数栈 UED 团队,致力于打造优秀的一站式数据中台产品.我们始终保持工匠精神,探索前端道路,为社区积累并传播经验价值. 本文作者:霜序 Formats ICU Message string ...

  8. TPLINK路由器重启脚本(软件版本3.0.0)

    ​ 家中的两个路由器全都是TPLink路由器,由于总出现时间一长就网卡的原因,写了这个重启脚本在每天凌晨五点的时候对路由器进行自动重启 使用方法: ​ self.logindata的值为登录时的jso ...

  9. 来个好玩的,用手机随时随地指挥你的 Cursor!

    告别束缚,用手机随时随地指挥你的 Cursor! 嘿,各位 Cursor 的忠实用户和效率达人们! 你是否曾经遇到过这样的场景:人不在Mac旁边,却突然灵感迸发,想要让 Cursor 帮你写点代码.整 ...

  10. Redis实战-缓存穿透、缓存雪崩、缓存击穿和缓存并发的区别和解决方案

    正常处理流程   客户端请求正常的时候,先读缓存,如果数据命中,则返回缓存的值:否则,把从存储层中读取出来的数据缓存至缓存,同时返回客户端.但是,为了保证系统高可用和高性能,设计一个缓存系统时必须考虑 ...