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 socket的端口扫描程序实例代码
Feb 09 Python
使用python3+xlrd解析Excel的实例
May 04 Python
python获取指定字符串中重复模式最高的字符串方法
Jun 29 Python
Python docx库用法示例分析
Feb 16 Python
python里dict变成list实例方法
Jun 26 Python
python把ipynb文件转换成pdf文件过程详解
Jul 09 Python
Python抓新型冠状病毒肺炎疫情数据并绘制全国疫情分布的代码实例
Feb 05 Python
详解Pycharm出现out of memory的终极解决方法
Mar 03 Python
python 带时区的日期格式化操作
Oct 23 Python
详解python使用金山词霸的翻译功能(调试工具断点的使用)
Jan 07 Python
Python面向对象之内置函数相关知识总结
Jun 24 Python
python内置模块之上下文管理contextlib
Jun 14 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
laravel5.1框架基础之Blade模板继承简单使用方法分析
2019/09/05 PHP
一样的table?不一样的table(可编辑状态table)
2012/09/19 Javascript
关于JavaScript与HTML的交互事件
2013/04/12 Javascript
Javascript之this关键字深入解析
2013/11/12 Javascript
Jquery中$.get(),$.post(),$.ajax(),$.getJSON()的用法总结
2013/11/14 Javascript
js中文逗号转英文实现
2014/02/11 Javascript
jQuery实现点击DIV同时点击CheckBox,并为DIV上背景色的实例
2017/12/18 jQuery
js判断节假日实例代码
2017/12/27 Javascript
vue引用js文件的多种方式(推荐)
2018/05/17 Javascript
JavaScript数组去重的几种方法
2019/04/07 Javascript
vue实现codemirror代码编辑器中的SQL代码格式化功能
2019/08/27 Javascript
原生js滑动轮播封装
2020/07/31 Javascript
在Python中使用HTML模版的教程
2015/04/29 Python
TensorFlow高效读取数据的方法示例
2018/02/06 Python
Python实现的微信好友数据分析功能示例
2018/06/21 Python
python爬虫之urllib3的使用示例
2018/07/09 Python
对TensorFlow的assign赋值用法详解
2018/07/30 Python
python利用wx实现界面按钮和按钮监听和字体改变的方法
2019/07/17 Python
django 邮件发送模块smtp使用详解
2019/07/22 Python
Python第三方包之DingDingBot钉钉机器人
2020/04/09 Python
Selenium元素定位的30种方式(史上最全)
2020/05/11 Python
通过实例解析Python RPC实现原理及方法
2020/07/07 Python
python爬取”顶点小说网“《纯阳剑尊》的示例代码
2020/10/16 Python
利用SVG和CSS3来实现一个炫酷的边框动画
2015/07/22 HTML / CSS
德国电子产品购物网站:TechInTheBasket德国
2018/12/07 全球购物
采用怎样的方法保证数据的完整性
2013/12/02 面试题
澳大利亚商务邀请函
2014/01/17 职场文书
战友聚会邀请函
2014/01/18 职场文书
2014年医学生毕业自我鉴定
2014/03/26 职场文书
反四风个人对照检查材料思想汇报
2014/09/25 职场文书
公司环境卫生管理制度
2015/08/05 职场文书
python3 实现mysql数据库连接池的示例代码
2021/04/17 Python
HTML+CSS+JS实现图片的瀑布流布局的示例代码
2021/04/22 HTML / CSS
Java基于Dijkstra算法实现校园导游程序
2022/03/17 Java/Android
golang语言指针操作
2022/04/14 Golang
MySQL池化框架学习接池自定义
2022/07/23 MySQL