Django+Celery学习笔记3——django+celery+redis实现异步任务与定时任务
引言
前面已经学习了celery+redis的异步和定时任务,下面介绍如何结合django来使用。
环境配置
在动手之前,一定要准备好的是环境,celery版本有很多,在使用过程中如何版本与django和redis版本不配套,将会很麻烦。
我这里的环境如下:
1 2 3 4 5 6 7 8 | celery==4.3.0 Django==2.2.2 django-celery-beat==1.5.0 django-celery-results==1.1.2 kombu==4.6.11 -- celery的依赖 PyMySQL==0.9.3 redis==3.2.1 python-crontab==2.5.1 |
创建项目
再复习一下创建django项目的命令,打开cmd窗口,输入:
1 | django-admin startproject 项目名 |
进入刚刚创建的项目根目录下,创建应用(app),输入:
1 | python manage.py startapp 应用名 |
在应用celerytest根目录下新建tasks.py文件,用于定义计划任务,注意此处只能以tasks命名(设计如此)
在django的项目目录(djangocelerydemo)中创建celery.py(与settings.py在同一级目录)文件,当然你也可以命名成celeryconfig.py文件,
这个文件没有要求,为啥要创建这个文件呢?
因为,要将Celery与Django项目一起使用,必须首先定义Celery库的实例,也就是创建celery的应用。文件放在此处,这种设置方法可以让celery自动在所有app中查找tasks文件,比较适合多人多APP同时开发的中大型项目 详情参考:Using Celery with Django
项目结构与配置
第一步,在djangocelerydemo/setting.py文件配置如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | # APP配置 INSTALLED_APPS = [ 'django.contrib.admin' , 'django.contrib.auth' , 'django.contrib.contenttypes' , 'django.contrib.sessions' , 'django.contrib.messages' , 'django.contrib.staticfiles' , 'django_celery_beat' , 'django_celery_results' , # 查看 celery 执行结果 'celerytest.apps.CelerytestConfig' , ] # 数据库配置 DATABASES = { 'default' : { 'ENGINE' : 'django.db.backends.mysql' , 'NAME' : 'djangocelerydemo' , 'HOST' : '127.0.0.1' , 'PORT' : '3306' , 'USER' : 'root' , 'PASSWORD' : '123456' , } } # 时区与celery相关配置 LANGUAGE_CODE = 'zh-hans' # 简体中文界面 TIME_ZONE = 'Asia/Shanghai' # 亚洲/上海时区 USE_I18N = True USE_L10N = True USE_TZ = False # 不使用国际标准时间 # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/2.2/howto/static-files/ STATIC_URL = '/static/' # django-celery-beat # django-celery-results CELERY_ENABLE_UTC = False # 不使用国际标准时间 CELERY_TIMEZONE = 'Asia/Shanghai' # 使用亚洲/上海时区 DJANGO_CELERY_BEAT_TZ_AWARE = False # 解决时区问题 CELERY_BROKER_URL = 'redis://127.0.0.1:6379/0' # 使用0号数据库 CELERY_BROKER_TRANSPORT = 'redis' # 使用redis作为中间件 CELERY_BEAT_SCHEDULER = 'django_celery_beat.schedulers:DatabaseScheduler' # 自定义调度类,使用Django的ORM CELERY_RESULT_BACKEND = 'django-db' # 任务结果,使用Django的ORM CELERY_ACCEPT_CONTENT = [ 'application/json' ] # 设置任务接收的序列化类型 CELERY_TASK_SERIALIZER = 'json' # 设置任务序列化方式 CELERY_RESULT_SERIALIZER = 'json' # 设置结果序列化方式 |
注意,如何你的函数返回的不是json, 将报错:
1 | kombu.exceptions.EncodeError: Object of type 'set' is not JSON serializable |
解决:
1 2 3 4 5 6 | CELERY_TASK_SERIALIZER = 'pickle' # 设置任务序列化方式 CELERY_RESULT_SERIALIZER = 'pickle' # 设置结果序列化方式 CELERY_ACCEPT_CONTENT = [ 'pickle' , 'json' ] # 设置任务接收的序列化类型 |
将之前setting中三个替换成这三个即可。原因:celery4版本的 默认使用 JSON 作为 serializer ,而 celery3版本的默认使用 pickle。所以为了让报错消除,需要添加以上设置。
第二步,在djangocelerydemo/celeryconfig.py文件配置如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | from __future__ import absolute_import, unicode_literals import os from celery import Celery, platforms from django.utils.datetime_safe import datetime # 获取当前文件夹名,即为该 Django 的项目名 project_name = os.path.split(os.path.abspath( '.' ))[-1] project_settings = '%s.settings' % project_name print(project_settings) # 设置默认celery命令行的环境变量 os.environ.setdefault( 'DJANGO_SETTINGS_MODULE' , 'djangocelerydemo.settings' ) # 实例化 Celery,项目名称 app = Celery( 'djangocelerydemo' ) # 解决时区问题 app.now = datetime.now # 使用 django 的 settings 文件配置 celery app.config_from_object( 'django.conf:settings' , namespace = 'CELERY' ) # 从所有应用中加载任务模块tasks.py app.autodiscover_tasks() # 解决celery不能root用户启动的问题 platforms.C_FORCE_ROOT = True |
第三步,在djangocelerydemo/__init__.py文件配置如下:
1 2 3 4 5 6 7 8 9 | # 引入celery实例对象 from __future__ import absolute_import, unicode_literals from djangocelerydemo.celeryconfig import app as celery_app __all__ = ( 'celery_app' ,) import pymysql pymysql.install_as_MySQLdb() |
这里不是app下面的__init__.py文件,是项目下面的。
第四步,在celerytest/tasks.py文件配置如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | # Create your tasks here from __future__ import absolute_import, unicode_literals from djangocelerydemo.celeryconfig import app @app.task def plan_task_1(): print( "任务_1已运行!" ) return { "任务_1:success" } @app.task def plan_task_2(): print( "任务_2已运行!" ) return { "任务_2:success" } |
第五步,最后别忘记配置apps.py了,如:
1 2 3 4 5 | from django.apps import AppConfig class CelerytestConfig(AppConfig): name = 'celerytest' |
第六步,数据迁移,因为没有模型,不需要激活,所以在项目根目录下直接输入:
1 | python manage.py migrate |
如果看到这7大金刚,证明你前面所有的工作已经正确的完成了。
温馨提示一下,上面的文件中,凡是用到celery文件的,需在第一行(习惯)加入代码:
1 | from __future__ import absolute_import, unicode_literals |
定时任务配置
上面基本上配置完后,创建管理员账号,如:
1 | python manage createsuperuser |
访问系统地址:http://127.0.0.1:1234/admin/
名词解析:
界面中 CELERY RESULTS 为 django_celery_results 创建的用于保存任务结果的数据库表。
Periodic tasks 下面则是由 django_celery_beat 创建的用于保存 Celery 任务及其执行规则的几张数据库表,具体含义如下:
1、Clocked:定义在具体某个时间点触发的执行规则
2、Crontabs:类似于 Linux 系统下 crontab 的语法,定时任务的执行时间
3、Intervals:定义任务重复执行的时间间隔
4、Periodic tasks:具体某个待执行的任务,需要与其他表(Clocked、Crontabs、Intervals、Solar events)中定义的执行规则相关联
5、Solar events:根据日升和日落等太阳运行轨迹确定执行规则
配置一个每十秒执行一次的规则,步骤如下:
配置定时计划任务,如图:
执行定时任务
前面已经讲过了异步任务和定时任务的命令,现在再次复习一下:
在项目根目录下执行异步任务命令:
1 | celery -A pro_name worker -l info |
这里还是要注意,win10会报一个这样的错误:
1 | ValueError: not enough values to unpack (expected 3, got 0) |
需要在上面命令加一个:
1 | celery -A pro_name worker -l info -P eventlet |
pro_name是django项目的名称
成功后,你会看见两个任务。
在项目根目录下执行定时任务命令:
1 | celery -A pro_name beat -l info |
每十秒执行一次:
执行的结果:
在web界面上可以查到:
这里需要注意:celery.backend_cleanup。有一个内建的周期性任务将删除过期的任务结果(celery.backend_cleanup),前提是 celery beat 已经被启用。这个任务每天上午4点运行。值 None 或者 0 意思是结果永不删除(取决于后端声明)
注意事项
这里如果安装celery或者运行任务调度器出现如下报错:
1 | ModuleNotFoundError: No module named 'vine.five' |
celery安装的时候,会把amqp、vine和kombu一起安装完成,所以一定要注意celery版本要和amqp、vine和kombu匹配,不然你将很麻烦。
正常版本是:
1 2 3 4 5 6 7 8 9 10 11 12 13 | # 这四个要匹配 amqp==2.6.1 celery==4.3.0 kombu==4.6.11 vine==1.3.0 # 另外匹配项 redis==3.2.1 Django==2.2.2 django-celery-beat==1.5.0 django-celery-results==1.1.2 PyMySQL==0.9.3 |
这样的话,你不会看到上面的报错信息。
总结
以上就是django+celery+redis实例,celery很强大,需要深入研究。如果对python测试开发相关技术感兴趣的伙伴,欢迎加入测试开发学习交流QQ群:696400122,不积跬步,无以至千里。
作者:全栈测试开发日记
出处:https://www.cnblogs.com/liudinglong/
csdn:https://blog.csdn.net/liudinglong1989/
微信公众号:全栈测试开发日记
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架