系列文章目录
第一章 三步解决Celery环境搭建问题-异步任务篇
第二章 三步解决Celery环境搭建问题-定时任务篇
第三章 三步解决Linux上未找到命令的问题
三步解决Celery环境搭建问题-定时任务篇
- 系列文章目录
- 前言
- 一、安装库
- 二、添加配置文件
- 三、测试定时任务调度
- 总结
- 归纳坑
- 坑1.bash: celery: 未找到命令
- 坑2.python3.7与celery不兼容问题
- 坑3.USE_TZ为False时不停的执行任务调度或者启动报错
- 坑4.ModuleNotFoundError: No module named ‘celery.five‘
- 坑5.celery TypeError: 'NoneType' object is not iterable
- 坑6.修改了tasks.py文件,执行结果未改变
- 坑7.admin页面的Peridsk.task页面打开报错
- 坑8.配置定时任务,也可以在celery.py里面写死
- 坑9.worker内存泄漏
- 坑10.多setting.py文件celery.py的重写方法
- 坑11.django+nginx+vue的admin样式丢失问题
- 坑12.django的migrate问题
- 参考文档
前言
大家好,我是一个刚踩过坑,拍拍灰尘,又回到坑里的菜鸟开发——clisten。
此篇主要记录在前一章节实现异步任务基础上,如何实现定时任务调度以及管理,主要基于以下开发环境:
- centos7
- django 3.1.7
- python 3.7.5
- redis 6.2.1
- celery 4.4.7
- django-celery-beat 1.5.0(待安装)
- django-celery-results 2.0.1(待安装)
提示:以下是本篇文章正文内容,下面案例可供参考
一、安装库
pip install django-celery-beat==1.5.0 # 任务调度程序
pip install django-celery-results==2.0.1 # 存储任务结果
注意:django-celery-beat、django-celery-results和celery之间有版本兼容性问题,pip完成后只要没有兼容性错误提示,就可以正常使用。
二、添加配置文件
文件结构如下:
- proj/
- manage.py
- proj/
- __init__.py
- settings.py
- celery.py
- ...
1.proj/proj/setting.py文件
文件中添加内容如下:
INSTALLED_APPS = (
...,
'django_celery_beat', # 任务调度程序
'django_celery_results', # 结果存储
)
...
# Celery 配置
CELERY_BROKER_URL = 'redis://localhost:6379/8' # Broker配置,使用Redis作为消息中间件
CELERY_TIMEZONE = 'Asia/Shanghai' # 时区设置
CELERY_BEAT_SCHEDULER = 'django_celery_beat.schedulers:DatabaseScheduler' # 修改celery-beat调度类
CELERY_RESULT_BACKEND = 'django-db' # django的ORM做后端结果存储
注意:django-celery-beat默认的调度类是celery.beat:PersistentScheduler,默认的调度文件是beat_scheduler,而使用django的ORM时,通过修改默认的调度类(也可以通过命令指定调度类),能动态配置定时任务。
2.数据库迁移
在添加完以上两处内容后,需要执行以下命令,完成数据库迁移
python manage makemigrations # 由于上面添加了,执行完会获取django-celery-beat和results的模型
python manage migrate # 获取模型后,执行数据库迁移,获取一堆celery-beat和results的相关表
成功迁移的数据库表示例图,如下:
- django_celery_beat_periodctask —存储可执行任务
- django_celery_results_taskresult —存储任务执行结果
三、测试定时任务调度
app结构如下:
- app/
- tasks.py
- models.py
- views.py
- urls.py
- ...
提示:结构用来对比,添加的内容示例见下文
1.proj/app/tasks.py文件
app中添加tasks.py文件,内容如下:
from celery import shared_task # 导入装饰器
import time
@shared_task
def hi():
time.sleep(10)
print("这是一条10s后的定时任务打印消息!")
def accuracy():
print("这是一条测试准确性的打印消息!")
2.注册用户、启动web服务、登录admin后台管理系统
如果你有admin后台(localhost:80/admin)的管理用户,请直接登录
python manage.py createsuperuser # 创建超级用户
python manage runserver localhost:80 # proj/manage.py同级目录,启动web服务命令
web服务成功启动后,登录后台,即可看到
- Periodic tasks —可执行任务页面,可对任务进行CRUD操作
- Task results —执行结果页面,主要查看任务执行状态等
3.启动redis、celery-worker和celery-beat
redis-server # 启动redis服务 -broker
成功启动redis,示例如图
celery -A worker proj -l INFO # proj/manage.py同级目录,启动worker命令
成功启动worker(若提示没celery命令,跳转坑1查看解决方法),示例如图
celery -A proj beat -l INFO # proj/manage.py同级目录,启动celery-beat命令
celery -A proj beat -l INFO --scheduler django_celery_beat.schedulers:DatabaseScheduler #也可以通过--scheduler方式指定调度类
成功启动clelery-beat,示例如图
3.注册并执行定时任务
如何在admin的后台中配置任务:点我直接翻到最后
注册任务示例如下:
按上述配置完成后,我们可以在celery-beat的终端里面看到,DatebaseScheduler:Schedule changed的打印,提示你动态的添加了定时任务,接下来celery-beat会调度,把任务放进队列中,交给worker去执行,在指定的定时周期,你可以在worker的终端窗口里面看到,接受到任务安排以及执行任务的打印信息,如下:
同时,你可以在执行结果页面查看执行状态如下:
至此,顺利实现定时任务的配置和调度。
总结
提示:个人总结,仅供参考
在程序启动时,没有次序要求,但是如果你先启动celery-worker,后启动redis,则worker的终端会一直提示你连接不上redis。如果你还没启动celery-beat,但启动worker时就有任务执行,说明队列中还有未完成的任务,是不是有点儿意思,坑也多,我总结了部分,希望对你有所帮助,respect!
归纳坑
坑1.bash: celery: 未找到命令
在pip list下安装了celey包,但是centos7下无法直接使用celery命令且报错,环境变量的问题,推荐解决方式:
提示:以上解法2,亲测可以执行celery命令,但是重新打开终端又失效
坑2.python3.7与celery不兼容问题
坑3.USE_TZ为False时不停的执行任务调度或者启动报错
错误示例 TypeError:can’t compare offset-naive and offset-aware datetimes
坑4.ModuleNotFoundError: No module named ‘celery.five‘
坑5.celery TypeError: ‘NoneType’ object is not iterable
坑6.修改了tasks.py文件,执行结果未改变
由于worker不能自动重载,所以ctrl+c终止后,重新运行worker程序即可
坑7.admin页面的Peridsk.task页面打开报错
可能是配置问题:
USE_TZ = False # 这改成False试试
坑8.配置定时任务,也可以在celery.py里面写死
celery中默认的调度文件是beat_schedule,这里你改写了这个配置
# 定时任务调度
from celery.schedules import crontab
from datetime import timedelta
app.conf.beat_schedule = {
"testSayHello": {
'task': 'users.tasks.sayhello',
'schedule': timedelta(seconds=5),
'args': ()
}
}
坑9.worker内存泄漏
在proj/proj/settings.py文件中添加内容示例
# celery设置
CELERY_WORKER_CONCURRENCY = 3 # 并发的worker数量
CELERY_WORKER_MAX_TASKS_PER_CHILD = 1 # 每个worker最多执行的任务数, 可防止内存泄漏
坑10.多setting.py文件celery.py的重写方法
坑11.django+nginx+vue的admin样式丢失问题
坑12.django的migrate问题
建议删除相关migrations记录和表,重新迁移
参考文档
定时任务配置: https://www.cnblogs.com/mldsh/p/13378044.html
celery-beat示例1: http://zhuoqun.info/article/203/#_label6
celery-beat示例2: https://blog.csdn.net/tbluhongxuan/article/details/107325686