Django+Django-Celery+Celery的整合实战


Posted in Python onJanuary 20, 2021

本篇文章主要是由于计划使用django写一个计划任务出来,可以定时的轮换值班人员名称或者定时执行脚本等功能,百度无数坑之后,终于可以凑合把这套东西部署上。本人英文不好,英文好或者希望深入学习或使用的人,建议去参考官方文档,而且本篇的记录不一定正确,仅仅实现crontab 的功能而已。

希望深入学习的人可以参考http://docs.jinkan.org/docs/celery/。

首先简单介绍一下,Celery 是一个强大的分布式任务队列,它可以让任务的执行完全脱离主程序,甚至可以被分配到其他主机上运行。我们通常使用它来实现异步任务(async task)和定时任务(crontab)。它的架构组成如下图

Django+Django-Celery+Celery的整合实战

可以看到,Celery 主要包含以下几个模块:

任务模块 Task

包含异步任务和定时任务。其中,异步任务通常在业务逻辑中被触发并发往任务队列,而定时任务由 Celery Beat 进程周期性地将任务发往任务队列。

消息中间件 Broker

Broker,即为任务调度队列,接收任务生产者发来的消息(即任务),将任务存入队列。Celery 本身不提供队列服务,官方推荐使用 RabbitMQ 和 Redis 等。

任务执行单元 Worker

Worker 是执行任务的处理单元,它实时监控消息队列,获取队列中调度的任务,并执行它。

任务结果存储 Backend

Backend 用于存储任务的执行结果,以供查询。同消息中间件一样,存储也可使用 RabbitMQ, Redis 和 MongoDB 等。

异步任务
使用 Celery 实现异步任务主要包含三个步骤:

  • 创建一个 Celery 实例
  • 启动 Celery Worker
  • 应用程序调用异步任务

一、快速入门

本地环境:

  • OS:centOS6.5
  • django-1.9
  • python-2.7.11
  • celery==3.1.20
  • django-celery

python、pip、django相关安装不在详写,直接参考百度即可;

pip install django==1.9   安装django 
pip install celery==3.1.20 安装celery
pip install django-celery  安装django-celery

安装如果有失败,所需要的依赖环境自行解决。例如:mysql-python等;
使用做redis作为消息中间件,安装redis:https://3water.com/article/96230.htm

二、创建django项目开始测试

1、创建django 工程 命名为djtest

django-admin.py startproject djtest1

2、创建app 命名为apps

cd djtest
python manage.py startapp apps1

3、创建完成后,django 目录结构如下:

djtest1
├── apps1
│ ├── admin.py
│ ├── apps.py
│ ├── init.py
│ ├── migrations
│ │ └── init.py
│ ├── models.py
│ ├── tests.py
│ └── views.py
├── djtest1
│ ├── init.py
│ ├── init.pyc
│ ├── settings.py
│ ├── settings.pyc
│ ├── urls.py
│ └── wsgi.py
└── manage.py

4、修改setting.py django配置文件,增加如下:

import djcelery ###
djcelery.setup_loader() ###
CELERY_TIMEZONE='Asia/Shanghai' #并没有北京时区,与下面TIME_ZONE应该一致
BROKER_URL='redis://192.168.217.77:16379/8' #任何可用的redis都可以,不一定要在django server运行的主机上
CELERYBEAT_SCHEDULER = 'djcelery.schedulers.DatabaseScheduler' ###
 
INSTALLED_APPS = (
  'django.contrib.admin',
  'django.contrib.auth',
  'django.contrib.contenttypes',
  'django.contrib.sessions',
  'django.contrib.messages',
  'django.contrib.staticfiles',
  'djcelery',  ### 加入djcelery应用
  'apps1',   ###   加入新创建的apps1
)
TIME_ZONE='Asia/Shanghai' ###

开头增加如上配置文件,根据实际情况配置redis的地址和端口,时区一定要设置为Asia/Shanghai。否则时间不准确回影响定时任务的运行。

上面代码首先导出djcelery模块,并调用setup_loader方法加载有关配置;注意配置时区,不然默认使用UTC时间会比东八区慢8个小时。其中INSTALLED_APPS末尾添加两项,分别表示添加celery服务和自己定义的apps服务。

5、编写celery文件:djtest/djtest/celery.py

#!/bin/python
from __future__ import absolute_import
 
import os
 
from celery import Celery
 
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'djtest1.settings')
#Specifying the settings here means the celery command line program will know where your Django project is. 
#This statement must always appear before the app instance is created, which is what we do next: 
from django.conf import settings
 
app = Celery('djtest1')
 
app.config_from_object('django.conf:settings')
#This means that you don't have to use multiple configuration files, and instead configure Celery directly from the Django settings.
#You can pass the object directly here, but using a string is better since then the worker doesn't have to serialize the object.
 
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)
#With the line above Celery will automatically discover tasks in reusable apps if you define all tasks in a separate tasks.py module.
#The tasks.py should be in dir which is added to INSTALLED_APP in settings.py. 
#So you do not have to manually add the individual modules to the CELERY_IMPORT in settings.py.
 
@app.task(bind=True)
def debug_task(self):
  print('Request: {0!r}'.format(self.request)) #dumps its own request information

6、修改djtest1/djtest1/init.py

#!/bin/python
from __future__ import absolute_import
 
# This will make sure the app is always imported when
# Django starts so that shared_task will use this app.
from .celery import app as celery_app

7、接下来编写你希望django去完成的app,本文中要编写的就是在INSTALLED_APPS中注册的apps。在celery.py中设定了对settings.py中INSTALLED_APPS做autodiscover_tasks,本文希望apps中能够接受这样的目录组织:所有的app都可以放到apps下面,而且每个app都有独立的目录,就和上面的app1、app2一样,每个app各自有各自的init.py和tasks.py(注意,每个app都需要init.py文件,可以是空白的)。但是这样的结构组织在启动时会报错说module apps找不到。然后在apps下增加了一个init.py文件,这时报错没了,但是apps下每个app的tasks.py中的任务函数还是无法被django和celery worker找到。

然后尝试了在apps1下面写一个__init__.py(空白)和task.py,所有的task function都写到tasks.py中,如下

8、同步数据库

python manage.py makemigrations
python manage.py migrate

9、创建超级用户

python manage.py createsuperuser
 
Username (leave blank to use 'work'): admin
Email address: yyc@taihe.com
Password: 
Password (again): 
Superuser created successfully.

10、启动django-web、启动celery beat 启动 celery worker进程

python manage.py runserver 0.0.0.0:8001#启动django的应用,可以动态的使用django-admin来管理任务
python manage.py celery beat #应该是用来监控任务变化的
python manage.py celery worker -c 6 -l debug #任务执行进程,worker进程

11、通过django-admin添加已注册的任务,并查看输出是否正常。

http://192.168.217.77:8001/admin/ 输入密码登录

(1)登录后添加任务:

Django+Django-Celery+Celery的整合实战

点击红线标记的列表,通过add来添加;

(2)

Django+Django-Celery+Celery的整合实战

点击进入以后,可以看到已经存在的任务,点击添加即可;

(3)

Django+Django-Celery+Celery的整合实战

按照提示,输入name,通过task(registered) 选择已经注册的函数服务。
选择运行模式,阻塞模式,为多长时间间隔运行一次,或者crontab形式运行。
点击Arguments(show),添加需要传入注册函数的参数。

(4)

Django+Django-Celery+Celery的整合实战

实例,具体名称以及运行时间以及传入参数等。

(5)

Django+Django-Celery+Celery的整合实战

保存之后,可以查看到列表。

(6)在python manage.py celery worker -c 6 -l debug启动的窗口可以看到如下的运行过程,证明已经生效。

Django+Django-Celery+Celery的整合实战

第一行红色标记,可以看到注册函数被调用,第二行红色标记,可以看到函数的返回值。

到此已经基本完成。在实际运用中,我们只需要修改或者添加到tasks.py文件里一些函数,让他注册到里边。我们从前台django-web写入任务,可以使其动态加载到任务。并且把正确的参数传过去,就可以正常执行。完成我们所想要的通过这个django-celery工具制作定期的备份、统一管理的crontab平台等。

参考文章:

http://blog.csdn.net/vintage_1/article/details/47664297
http://docs.jinkan.org/docs/celery/getting-started/introduction.html
http://www.jianshu.com/p/f78ed01969b3
http://www.jianshu.com/p/b7f843f21c46

到此这篇关于Django+Django-Celery+Celery的整合实战的文章就介绍到这了,更多相关Django Celery实战内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
在Python程序中操作文件之isatty()方法的使用教程
May 24 Python
浅析Python的web.py框架中url的设定方法
Jul 11 Python
Python制作简易注册登录系统
Dec 15 Python
Python入门_学会创建并调用函数的方法
May 16 Python
Python实现的购物车功能示例
Feb 11 Python
python XlsxWriter模块创建aexcel表格的实例讲解
May 03 Python
详解Python匿名函数(lambda函数)
Apr 19 Python
Python内置方法实现字符串的秘钥加解密(推荐)
Dec 09 Python
python标识符命名规范原理解析
Jan 10 Python
python datetime处理时间小结
Apr 16 Python
在django中form的label和verbose name的区别说明
May 20 Python
Python调用C/C++的方法解析
Aug 05 Python
详解Python Celery和RabbitMQ实战教程
Jan 20 #Python
详解python3类型注释annotations实用案例
Jan 20 #Python
python-jwt用户认证食用教学的实现方法
Jan 19 #Python
使用Python爬虫爬取小红书完完整整的全过程
Jan 19 #Python
python 自动识别并连接串口的实现
Jan 19 #Python
python爬取抖音视频的实例分析
Jan 19 #Python
python中的插入排序的简单用法
Jan 19 #Python
You might like
php以fastCGI的方式运行时文件系统权限问题及解决方法
2015/05/11 PHP
什么是OneThink oneThink后台添加插件步骤
2016/04/13 PHP
thinkPHP5.0框架安装教程
2017/03/25 PHP
jquery ready(fn)事件使用介绍
2013/08/21 Javascript
jQuery遮罩层实现方法实例详解(附遮罩层插件)
2015/12/08 Javascript
浅谈js中对象的使用
2016/08/11 Javascript
微信公众平台开发教程(五)详解自定义菜单
2016/12/02 Javascript
原生JS实现《别踩白块》游戏(兼容IE)
2017/02/20 Javascript
bootstrap3 dialog 更强大、更灵活的模态框
2017/04/20 Javascript
Vue实现类似Spring官网图片滑动效果方法
2019/03/01 Javascript
vue+php实现的微博留言功能示例
2019/03/16 Javascript
使用React手写一个对话框或模态框的方法示例
2019/04/25 Javascript
[01:21:07]EG vs Liquid 2018国际邀请赛淘汰赛BO3 第一场 8.25
2018/08/29 DOTA
python网页请求urllib2模块简单封装代码
2014/02/07 Python
Python中内建函数的简单用法说明
2016/05/05 Python
用pickle存储Python的原生对象方法
2017/04/28 Python
python3实现UDP协议的服务器和客户端
2017/06/14 Python
python实现微信远程控制电脑
2018/02/22 Python
python Celery定时任务的示例
2018/03/13 Python
pandas实现选取特定索引的行
2018/04/20 Python
python学习基础之循环import及import过程
2018/04/22 Python
python对csv文件追加写入列的方法
2019/08/01 Python
python scrapy爬虫代码及填坑
2019/08/12 Python
python写入数据到csv或xlsx文件的3种方法
2019/08/23 Python
Python 3.8正式发布重要新功能一览
2019/10/17 Python
Numpy将二维数组添加到空数组的实现
2019/12/05 Python
scrapy redis配置文件setting参数详解
2020/11/18 Python
幼师专业毕业生自荐信
2013/09/29 职场文书
运动会广播稿50字
2014/01/26 职场文书
毕业生自荐书
2014/02/02 职场文书
指导教师评语
2014/04/26 职场文书
物业管理委托协议(2篇)
2014/09/23 职场文书
党员示范岗材料
2014/12/19 职场文书
保险公司反洗钱宣传活动总结
2015/05/08 职场文书
使用Html+Css实现简易导航栏功能(导航栏遇到鼠标切换背景颜色)
2021/04/07 HTML / CSS
springboot创建的web项目整合Quartz框架的项目实践
2022/06/21 Java/Android