Django中使用Celery实现定时任务(用djcelery)
一.引言
Django是python语言下的一个比较热门的Web框架,越来越多的企业和开发者使用Django实现自己的Web服务器。在Web服务器开发过程中,有时候我们不仅仅是要实现Web服务器端和用户端的简单逻辑交互,还要实现一些定时任务。举出以下的例子:
定期删除或缓存Redis数据库的记录
为了追求更高的数据库访问性能,我把Redis作为MySql数据库的缓存。把常访问的数据放在Redis中,然后定时存储到Mysql中。并且把过期的Redis数据删掉.那么这个时候,就需要定时去完成这个任务。生成报表
打个比方,你有一个Web电商服务器,每天用户都在会在上面购物。为了很方便的统计出每个用户每个月的消费金额,你在数据库中设计了一张月统计报表。然后使用定时任务,在每个月的1号进行统计,检索数据库,计算出每个用户上个月的的消费金额,逐个存储到月统计报表中。那么这个生成报表的任务就是定时完成的,也就是前面提到的每个月的1号。定时发送消息
再如:当你的网站上用户生日来临,你希望在他生日那天,给用户的邮箱发送生日快乐的祝福。那么这也是定时任务实现的。
上面这些的例子,都是需要定时任务。在Python中,我们使用的Celery模块完成这项任务。网络上关于Celery的博文很多,大多博文的逻辑比较混乱,因此就有了这篇博文。希望读者有个清晰的认识,并且很好的实战出来。
此篇博文没有介绍Celery的工作原理,诸如Broker,Worker等等。在实战之前,这些概念必须要理解清楚。由于网上已经有很多这样的内容,我在文章结尾处贴出了一些参考文档,方便读者学习。
二.Celery,Django和Djcelery
始终明确的是:
Celery是Python的第三方库,它可以用于是任何的Python的项目中,因为我们始终可以把Celery看成一个独立的模块去操纵其它的模块。因此,我们也可以在Django项目中使用的Celery,但值得注意的是,在Django中使用Celery的方式有两种:
- 仅使用Celery。
- 同时使用Celery + djcelery .
方法1: 相当于中Django中加入了一个Celery的任务脚本,为了操纵Django,因此需要额外在Celery中配置Django环境,才能操作Django的数据库。
方法2: 由于使用了djcelery,可以在任务中方便的直接操作Django数据库,而且最终的任务可以在Django的后台中查看和修改相关的任务。
两种方法的选择:
从上面的描述看,方法1比方法2少引入一个djcelery模块,缺点是需要自己配置与Django结合的环境。而方法2,比较方便省心,还能在Django后台管理自己的任务。因此如果你在Django中使用Celery,我强烈推荐方法2。
这两种方法我都写了相应的博文。此篇博文讲述了使用djcelery的方法2,至于不用的djcelery仅仅使用Celery模块的方法1,请参考我的另一篇博文:
Django中使用Celery实现定时任务(不使用djcelery)
但它们本质上是一样的。
三. Django目录结构
下面展示了一个Django项目的目录结构示例:
- app
- admin.py
- views.py
- urls.py
- models.py
- tasks.py
- pro
- settings.py
- urls.py
- urls.py
- models.py
- manage.py
注意,上述目录中的tasks.py
文件是我新建的,放在app的目录下,整个Celery任务,我只新建了这一个文件。
四. 配置setting.py
为了设置Celery,我们需要对setting.py文件进行配置,过程如下:
1.加入djcelery
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'djcelery', #此处是新加入的djcelery
'app',
)
上述 INSTALLED_APPS
中我省略了无关的模块,注意加入djcelery
即可。
2. 设置celery参数
我在setting.py的文件结尾处,加入了如下的celery参数配置,先贴代码,再解释。
import djcelery
djcelery.setup_loader()
BROKER_URL = 'redis://127.0.0.1:6379/6'
CELERY_IMPORTS = ('app.tasks', )
CELERY_TIMEZONE = TIME_ZONE
CELERYBEAT_SCHEDULER = 'djcelery.schedulers.DatabaseScheduler'
# 下面是定时任务的设置,我一共配置了三个定时任务.
from celery.schedules import crontab
CELERYBEAT_SCHEDULE = {
#定时任务一: 每24小时周期执行任务(del_redis_data)
u'删除过期的redis数据': {
"task": "app.tasks.del_redis_data",
"schedule": crontab(hour='*/24'),
"args": (),
},
#定时任务二: 每天的凌晨12:30分,执行任务(back_up1)
u'生成日报表': {
'task': 'app.tasks.back_up1',
'schedule': crontab(minute=30, hour=0),
"args": ()
},
#定时任务三:每个月的1号的6:00启动,执行任务(back_up2)
u'生成统计报表': {
'task': 'app.tasks.back_up2',
'schedule': crontab(hour=6, minute=0, day_of_month='1'),
"args": ()
},
}
上述代码释义:
当djcelery.setup_loader()运行时,Celery便会去查看INSTALLD_APPS下包含的所有app目录中的tasks.py文件,找到标记为task的方法,将它们注册为celery task。
1.
BROKER_URL = 'redis://127.0.0.1:6379/6'
broker是代理人,它负责分发任务给worker去执行。我使用的是Redis作为broker,当然你也可以用其它的broker,比如官方就比较推荐使用RabbitMQ.
有的博客中提到要配置关键字:CELERY_RESULT_BACKEND
,例如:
CELERY_RESULT_BACKEND = 'amqp://guest@localhost//' #可以不用写
我没有配置这个关键字。因为如果没有配置,此时Django会使用默认的数据库(也是你指定的orm数据库),作为它的结果作为它的backend。因此你也可以不用写,使用Django默认设置的数据库就很好。
2.
CELERY_IMPORTS = ('app.tasks', )
CELERY_TIMEZONE = TIME_ZONE
CELERYBEAT_SCHEDULER = 'djcelery.schedulers.DatabaseScheduler'
上面第一句是导入目标任务文件,第二句是设置时区,第三句表示使用了django-celery默认的数据库调度模型,任务执行周期都被存在默认指定的orm数据库中.
更深入的Celery配置:(http://www.cnblogs.com/ajianbeyourself/p/4950758.html)
3.
from celery.schedules import crontab
CELERYBEAT_SCHEDULE = {
#定时任务一: 每24小时周期执行任务(del_redis_data)
u'删除过期的redis数据': {
"task": "app.tasks.del_redis_data",
"schedule": crontab(hour='*/24'),
"args": (),
},
上面是设置定时的时间配置,关于crontab
的用法,官方的文档讲解的十分详尽(文档末尾的表格):
http://docs.celeryproject.org/en/latest/userguide/periodic-tasks.html
5.Tasks任务
每个任务本质上就是一个函数,在tasks.py中,写入你想要执行的函数即可。我的tasks.py如下:我写的每个任务又臭又长,因此具体的细节就省略了。
# coding=utf-8
from celery import task
@task()
def del_redis_data():
# 此处是一个删除redis数据的操作。具体略过
@task()
def back_up1():
# 此处是一个备份到日报表的操作。具体略过
@task()
def back_up2():
# 此处是一个生成统计报表的操作。具体略过
如果读者需要自己实现一个定时任务,那么上述的task函数必然要自己去定义,我只提供了参考。我上面的三个任务,分别对应了setting.py
文件的CELERYBEAT_SCHEDULE
的三个定时配置。
要记住的是,任务只是一个函数,这个函数什么时候调用,取决你在setting.py
中的配置。
6.启动定时任务
待续:
登录到Django后台,可以看到
7.推荐文章
1.更深入的Celery配置:(http://www.cnblogs.com/ajianbeyourself/p/4950758.html)
Django中使用Celery实现定时任务(用djcelery)的更多相关文章
- celery介绍、架构、快速使用、包结构,celery执行异步、延迟、定时任务,django中使用celery,定时更新首页轮播图效果实现,数据加入redis缓存的坑及解决
今日内容概要 celery介绍,架构 celery 快速使用 celery包结构 celery执行异步任务 celery执行延迟任务 celery执行定时任务 django中使用celery 定时更新 ...
- Django 中使用 Celery
起步 在 <分布式任务队列Celery使用说明> 中介绍了在 Python 中使用 Celery 来实验异步任务和定时任务功能.本文介绍如何在 Django 中使用 Celery. 安装 ...
- Python—在Django中使用Celery
一.Django中的请求 Django Web中从一个http请求发起,到获得响应返回html页面的流程大致如下: http请求发起 经过中间件 http handling(request解析) ur ...
- Django中使用Celery
一.前言 Celery是一个基于python开发的分布式任务队列,如果不了解请阅读笔者上一篇博文Celery入门与进阶,而做python WEB开发最为流行的框架莫属Django,但是Django的请 ...
- Celery简介以及Django中使用celery
目录 Celery简介 消息中间件 任务执行单元 任务结果存储 使用场景 Celery的安装和配置 Celery执行异步任务 基本使用 延时任务 定时任务 异步处理Django任务 案例: Celer ...
- 四、Django中使用celery
项目跟目录创建celery包,目录结构如下: mycelery/ ├── config.py ├── __init__.py ├── main.py └── sms/ ├── __init__.py ...
- Django中使用Celery,定制应用程序中定义的shared_task未在定期任务管理页面的注册任务中显示
解决办法: 在项目 proj/proj/celery.py文件中,看到下面这行配置: celery_app.config_from_object('django.conf:settings', nam ...
- Django项目中使用celery做异步任务
异步任务介绍 在写项目过程中经常会遇到一些耗时的任务, 比如:发送邮件.发送短信等等~.这些操作如果都同步执行耗时长对用户体验不友好,在这种情况下就可以把任务放在后台异步执行 celery就是用于处理 ...
- celery在Django中的集成使用
继上回安装和使用Redis之后,看看如何在Django中使用Celery.Celery是Python开发分布式任务列队的处理库.可以异步分布式地异步处理任务,也可定时执行任务等等.通常我们可以在Dja ...
随机推荐
- 练习SQL代码
---------PS:但凡有聚合函数(where),必然后Group by,Group by后面跟having ---------面试题 SELECT name,sum(fen) as s from ...
- 用vbs打开文件
set ws=createobject("wscript.shell")ws.run"打开文件所使用的程序+空格+程序路径",x,ture Run方法有三个参数 ...
- FastAdmin 开发第三天:安装 FastAdmin
环境安装安装好后就可以安装 FastAdmin 了. 根据文档说明安装步骤如下,推荐使用命令行安装: 克隆FastAdmin到你本地 git clone https://git.oschina.net ...
- spark之 spark 2.2.0 Standalone安装、wordCount演示
说明:前提安装好hadoop集群,可参考 http://blog.csdn.net/zhang123456456/article/details/77621487 一. scala 安装 1.下载 s ...
- 前端可视化建模技术概览,包括:GoJS
我推荐使用的: 库 网址 备注 GoJS https://gojs.net/latest/samples/flowchart.html 推荐使用 相关文章: 前端可视化建模技术概览:http://le ...
- Open Flash Chart 之线图
天公司要求开发一个曲线图,简单看了一下之前公司的一个系统,发现一个曲线图效果还不错,查了一下叫OpenFlashChart,还是很不错的,很多人用.研究了一下,发现还不错,特地写了个DEMO测试下. ...
- java判断字符串中是否含有中文
/** * 判断字符串中是否含有中文 */ public static boolean isCNChar(String s){ boolean booleanValue = false; for(in ...
- 术语-服务:PaaS
ylbtech-术语-服务:PaaS PaaS是Platform-as-a-Service的缩写,意思是平台即服务. 把服务器平台作为一种服务提供的商业模式.通过网络进行程序提供的服务称之为SaaS( ...
- Js/jquery获取当前日期时间及其它操作
var myDate = new Date(); myDate.getYear(); //获取当前年份(2位) myDate.getFullYear(); //获取完整的年份(4位,1970-???? ...
- MySQL-Jira双机热备
主服务器:192.168.1.23 从服务器:192.168.1.243 一.主服务器Master配置 1. 创建同步账号.赋权 在主服务器上为从服务器建立一个连接帐户,此处用root,该帐户必须授予 ...