详解django+django-celery+celery的整合实战


Posted in Python onMarch 19, 2019

本篇文章主要是由于计划使用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:

二、创建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中,如下**

from __future__ import absolute_import

from celery import task

from celery import shared_task

#from celery.task import tasks 
#from celery.task import Task 

@task()
#@shared_task
def add(x, y):
  print "%d + %d = %d"%(x,y,x+y)
  return x+y
#class AddClass(Task):
#  def run(x,y):
#    print "%d + %d = %d"%(x,y,x+y)
#    return x+y
#tasks.register(AddClass)

@shared_task
def mul(x, y):
  print "%d * %d = %d"%(x,y,x*y)
  return x*y

@shared_task
def sub(x, y):
  print "%d - %d = %d"%(x,y,x-y)
  return x-y

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平台等。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python类的继承实例详解
Mar 30 Python
理解Python中的绝对路径和相对路径
Aug 30 Python
python登录并爬取淘宝信息代码示例
Dec 09 Python
python自动化之Ansible的安装教程
Jun 13 Python
python tkinter实现界面切换的示例代码
Jun 14 Python
使用Filter过滤python中的日志输出的实现方法
Jul 17 Python
Python closure闭包解释及其注意点详解
Aug 28 Python
Python3使用xml.dom.minidom和xml.etree模块儿解析xml文件封装函数的方法
Sep 23 Python
Python文件操作函数用法实例详解
Dec 24 Python
Tensorflow训练MNIST手写数字识别模型
Feb 13 Python
Python 自由定制表格的实现示例
Mar 20 Python
python生成word合同的实例方法
Jan 12 Python
详解Python正则表达式re模块
Mar 19 #Python
python matplotlib画图库学习绘制常用的图
Mar 19 #Python
详解python的四种内置数据结构
Mar 19 #Python
python3使用matplotlib绘制条形图
Mar 25 #Python
python3使用matplotlib绘制散点图
Mar 19 #Python
浅谈PYTHON 关于文件的操作
Mar 19 #Python
python scatter散点图用循环分类法加图例
Mar 19 #Python
You might like
生成静态页面的PHP类
2006/07/15 PHP
一段防盗连的PHP代码
2006/12/06 PHP
ajax php传递和接收变量实现思路及代码
2012/12/19 PHP
PHP实现数字补零功能的2个函数介绍
2014/05/12 PHP
PHP文件锁定写入实例解析
2014/07/14 PHP
php结合正则批量抓取网页中邮箱地址
2015/05/19 PHP
PHP有序表查找之插值查找算法示例
2018/02/10 PHP
Yii2.0框架实现带分页的多条件搜索功能示例
2019/02/20 PHP
PHP设计模式之PHP迭代器模式讲解
2019/03/22 PHP
由prototype_1.3.1进入javascript殿堂-类的初探
2006/11/06 Javascript
Jquery.LazyLoad.js修正版下载,实现图片延迟加载插件
2011/03/12 Javascript
js写一个弹出层并锁屏效果实现代码
2012/12/07 Javascript
javascript+xml实现简单图片轮换(只支持IE)
2012/12/23 Javascript
jquery遍历select元素(实例讲解)
2013/12/31 Javascript
scrollWidth,clientWidth,offsetWidth的区别
2015/01/13 Javascript
Js和JQuery获取鼠标指针坐标的实现代码分享
2015/05/25 Javascript
JQuery中DOM事件合成用法实例分析
2015/06/13 Javascript
Underscore源码分析
2015/12/30 Javascript
jQuery ajax应用总结
2016/06/02 Javascript
微信小程序 教程之列表渲染
2016/10/18 Javascript
利用JS轻松实现获取表单数据
2016/12/06 Javascript
vue-cli如何快速构建vue项目
2017/04/26 Javascript
Angular 5.x 学习笔记之Router(路由)应用
2018/04/08 Javascript
vue-cli扩展多模块打包的示例代码
2018/04/09 Javascript
vue基础之事件v-onclick="函数"用法示例
2019/03/11 Javascript
vue 清空input标签 中file的值操作
2020/07/21 Javascript
[47:04]EG vs RNG 2019国际邀请赛小组赛 BO2 第二场 8.16
2019/08/18 DOTA
python写的一个squid访问日志分析的小程序
2014/09/17 Python
Python实现爬取逐浪小说的方法
2015/07/07 Python
在Pycharm中对代码进行注释和缩进的方法详解
2019/01/20 Python
Desigual英国官网:在线购买原创服装
2018/03/09 全球购物
JavaScript实现前端网页版倒计时
2021/03/24 Javascript
应届中专生自荐书范文
2014/02/13 职场文书
开工仪式主持词
2014/03/20 职场文书
优秀家长自荐材料
2014/08/26 职场文书
2014年干部培训工作总结
2014/12/17 职场文书