Django进阶:万字长文教你使用Celery执行异步和周期性任务(多图)

Django Web项目中我们经常需要执行耗时的任务比如发送邮件、调用第三方接口、批量处理文件等等,将这些任务异步化放在后台运行可以有效缩短请求响应时间。另外服务器上经常会有定时任务的需求,比如清除缓存、备份数据库等工作。Celery是一个高效的异步任务队列/基于分布式消息传递的作业队列,可以轻松帮我们在Django项目中设置执行异步和周期性任务。

本文将详细演示如何在Django项目中集成Celery设置执行异步和周期性任务并总结下一些高级使用技巧和注意事项。

原文首发大江狗技术博客(https://pythondjango.cn), 点击阅读原文可以跳转。

  • https://pythondjango.cn/django/advanced/12-sync-periodic-tasks-with-celery/

目录

Celery的工作原理安装项目依赖文件Celery配置测试Celery是否工作正常编写任务异步调用任务查看任务执行状态及结果设置定时和周期性任务配置文件添加任务Django Admin添加周期性任务通过Crontab设置定时任务启动任务调度器beatFlower监控任务执行状态Celery高级用法与注意事项给任务设置最大重试次数不同任务交由不同Queue处理忽略不想要的结果避免启动同步子任务Django的模型对象不应该作为参数传递使用on_commit函数处理事务小结

Celery的工作原理

Celery是一个高效的基于分布式消息传递的作业队列。它主要通过消息(messages)传递任务,通常使用一个叫Broker(中间人)来协调client(任务的发出者)和worker(任务的处理者)。clients发出消息到队列中,broker将队列中的信息派发给 Celery worker来处理。Celery本身不提供消息服务,它支持的消息服务(Broker)有RabbitMQ和Redis。小编一般推荐Redis,因为其在Django项目中还是首选的缓存后台。

整个工作流程如下所示:

安装项目依赖文件

本项目使用了最新Django(3.2)和Celery版本(Celery 5)。因为本项目使用Redis做消息队列的broker,所以还需要安装redis (Windows下安装和启动redis参见菜鸟教程)。另外如果你要设置定时或周期性任务,还需要安装django-celery-beat

 # pip安装必选
 Django==3.2
 celery==5.0.5
 redis==3.5.3
 
 # 可选,windows下运行celery 4以后版本,还需额外安装eventlet库
 eventlet 
 
 # 推荐安装, 需要设置定时或周期任务时安装,推荐安装
 django-celery-beat==2.2.0
 
 # 视情况需要,需要存储任务结果时安装,视情况需要
 django-celery-results==2.0.1
 
 # 视情况需要,需要监控celery运行任务状态时安装
 folower==0.9.7

Celery配置

在正式使用celerydjango-celery-beat之前,你需要做基础的配置。假如你的Django项目文件夹布局如下所示,你首先需要在myproject/myproject目录下新增celery.py并修改__init__.py

 - myproject/
   - manage.py
   - project/
     - __init__.py # 修改这个文件
     - celery.py # 新增这个文件
     - asgi.py
     - settings.py
     - urls.py
     - wsgi.py

新建celery.py,添加如下代码:

 import os
 from celery import Celery
 
 # 设置环境变量
 os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.settings')
 
 # 实例化
 app = Celery('myproject')
 
 # namespace='CELERY'作用是允许你在Django配置文件中对Celery进行配置
 # 但所有Celery配置项必须以CELERY开头,防止冲突
 app.config_from_object('django.conf:settings', namespace='CELERY')
 
 # 自动从Django的已注册app中发现任务
 app.autodiscover_tasks()
 
 # 一个测试任务
 @app.task(bind=True)
 def debug_task(self):
     print(f'Request: {self.request!r}')

修改__init__.py,如下所示:

 from .celery import app as celery_app
 __all__ = ('celery_app',)

接下来修改Django项目的settings.py,添加Celery有关配置选项,如下所示:

 # 最重要的配置,设置消息broker,格式为:db://user:password@host:port/dbname
 # 如果redis安装在本机,使用localhost
 # 如果docker部署的redis,使用redis://redis:6379
 CELERY_BROKER_URL = "redis://127.0.0.1:6379/0"
 
 # celery时区设置,建议与Django settings中TIME_ZONE同样时区,防止时差
 # Django设置时区需同时设置USE_TZ=True和TIME_ZONE = 'Asia/Shanghai'
 CELERY_TIMEZONE = TIME_ZONE

其它Celery常用配置选项包括:

 # 为django_celery_results存储Celery任务执行结果设置后台
 # 格式为:db+scheme://user:password@host:port/dbname
 # 支持数据库django-db和缓存django-cache存储任务状态及结果
 CELERY_RESULT_BACKEND = "django-db"
 # celery内容等消息的格式设置,默认json
 CELERY_ACCEPT_CONTENT = ['application/json', ]
 CELERY_TASK_SERIALIZER = 'json'
 CELERY_RESULT_SERIALIZER = 'json'
 
 # 为任务设置超时时间,单位秒。超时即中止,执行下个任务。
 CELERY_TASK_TIME_LIMIT = 5
 
 # 为存储结果设置过期日期,默认1天过期。如果beat开启,Celery每天会自动清除。
 # 设为0,存储结果永不过期
 CELERY_RESULT_EXPIRES = xx
 
 # 任务限流
 CELERY_TASK_ANNOTATIONS = {'tasks.add': {'rate_limit': '10/s'}}
 
 # Worker并发数量,一般默认CPU核数,可以不设置
 CELERY_WORKER_CONCURRENCY = 2
 
 # 每个w
  • 20
    点赞
  • 114
    收藏
    觉得还不错? 一键收藏
  • 15
    评论
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值