Django中使用Celery实现定时任务(用djcelery)

[TOC]

一.引言

Django是python语言下的一个比较热门的Web框架,越来越多的企业和开发者使用Django实现自己的Web服务器。在Web服务器开发过程中,有时候我们不仅仅是要实现Web服务器端和用户端的简单逻辑交互,还要实现一些定时任务。举出以下的例子:  

  1. 定期删除或缓存Redis数据库的记录

    为了追求更高的数据库访问性能,我把Redis作为MySql数据库的缓存。把常访问的数据放在Redis中,然后定时存储到Mysql中。并且把过期的Redis数据删掉.那么这个时候,就需要定时去完成这个任务。

  2. 生成报表   

    打个比方,你有一个Web电商服务器,每天用户都在会在上面购物。为了很方便的统计出每个用户每个月的消费金额,你在数据库中设计了一张月统计报表。然后使用定时任务,在每个月的1号进行统计,检索数据库,计算出每个用户上个月的的消费金额,逐个存储到月统计报表中。那么这个生成报表的任务就是定时完成的,也就是前面提到的每个月的1号。

  3. 定时发送消息

    再如:当你的网站上用户生日来临,你希望在他生日那天,给用户的邮箱发送生日快乐的祝福。那么这也是定时任务实现的。

上面这些的例子,都是需要定时任务。在Python中,我们使用的Celery模块完成这项任务。网络上关于Celery的博文很多,大多博文的逻辑比较混乱,因此就有了这篇博文。希望读者有个清晰的认识,并且很好的实战出来。

此篇博文没有介绍Celery的工作原理,诸如Broker,Worker等等。在实战之前,这些概念必须要理解清楚。由于网上已经有很多这样的内容,我在文章结尾处贴出了一些参考文档,方便读者学习。


二.Celery,Django和Djcelery

始终明确的是:

Celery是Python的第三方库,它可以用于是任何的Python的项目中,因为我们始终可以把Celery看成一个独立的模块去操纵其它的模块。因此,我们也可以在Django项目中使用的Celery,但值得注意的是,在Django中使用Celery的方式有两种:

  1. 仅使用Celery。
  2. 同时使用Celery + djcelery .

方法1: 相当于中Django中加入了一个Celery的任务脚本,为了操纵Django,因此需要额外在Celery中配置Django环境,才能操作Django的数据库。

方法2: 由于使用了djcelery,可以在任务中方便的直接操作Django数据库,而且最终的任务可以在Django的后台中查看和修改相关的任务。

两种方法的选择:

从上面的描述看,方法1比方法2少引入一个djcelery模块,缺点是需要自己配置与Django结合的环境。而方法2,比较方便省心,还能在Django后台管理自己的任务。因此如果你在Django中使用Celery,我强烈推荐方法2。

此篇博文讲述了使用方法2,但它们本质上是一样的。


三. 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://[email protected]//‘ #可以不用写

我没有配置这个关键字。因为如果没有配置,此时Django会使用默认的数据库(也是你指定的orm数据库),作为它的结果作为它的backend。因此你也可以不用写,使用Django默认设置的数据库就很好。

  1. 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)

  1. 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后台,可以看到数据库中有任务的参数,图日后补上。

然后启动终端,切换到Django项目的根目录下,运行:

celery worker -A 项目名 -l info  

这条命令用于启动worker, worker本质上执行任务的线程,就是一个干苦力的工人。

celery beat -A 项目名 -l info

上面这条任务用于启动beater,它就像一个领导,负责把任务分发给工人。

到直接,这篇博文基本就结束了,由于两次更新的时间间隔比较长,最初的思路都记不清了。当然,你肯定有一个重要的疑问,那就是如果任务因为系统重启或者其它原因崩溃了怎么重启呢?对于linux 系统,supervisor可以托管这两条命令,如果任务没有跑起来,它可以自己重启启动任务,这样,就能保证服务器端的定时任务不会因为一些原因崩溃掉。

7.推荐文章

1.更深入的Celery配置:(http://www.cnblogs.com/ajianbeyourself/p/4950758.html)

原文地址:https://www.cnblogs.com/crb912/p/8976937.html

时间: 2024-10-17 00:28:27

Django中使用Celery实现定时任务(用djcelery)的相关文章

Django 中使用 Celery

起步 在 <分布式任务队列Celery使用说明> 中介绍了在 Python 中使用 Celery 来实验异步任务和定时任务功能.本文介绍如何在 Django 中使用 Celery. 安装 pip install django-celery 这个命令使用的依赖是 Celery 3.x 的版本,所以会把我之前安装的 4.x 卸载,不过对功能上并没有什么影响.我们也完全可以仅用Celery在django中使用,但使用 django-celery 模块能更好的管理 celery. 使用 可以把有关 C

django中使用celery发送邮件

1.安装两个包:celery, django-celery pip install celery==3.1.25 pip install django-celery==3.1.17 2.配置 项目目录/项目名目录/settings.py 1.将celery添加到注册应用中 INSTALLED_APPS = ( ......, 'djcelery', ...... ) 2.配置celery import djcelery djcelery.setup_loader()  # 去每一个应用目录下找

Django中使用Celery,定制应用程序中定义的shared_task未在定期任务管理页面的注册任务中显示

解决办法: 在项目 proj/proj/celery.py文件中,看到下面这行配置: celery_app.config_from_object('django.conf:settings', namespace='CELERY') 修改成下面所示结果: celery_app.config_from_object(settings, namespace='CELERY') 除此之外,还需要在proj/proj/celery.py文件头部引入settings配置: from django.conf

django中使用celery

创建django项目celery_demo, 创建应用demo: django-admin startproject celery_demo python manage.py startapp demo #celery.pyfrom celery import Celery from django.conf import settings import os # 为celery设置环境变量 os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'cele

django中使用celery异步发送邮件问题

通过提示说明Celery 4.x 需要Django1.11或者后面的版本,可是使用的是django1.8.2的版本,最先以为是自己什么地方配置出错了,找了很久也没有找到. 任务队列启动没错,任务处理启动也没问题,打开输入地址就报错. 最终看到使用的是Celery4.3.0,然后改成4.1.1版本就可以使用了. 具体问题没找到,应该是新版本加入了一些东西,以后再来研究. 原文地址:https://www.cnblogs.com/-666/p/11279843.html

Celery完成定时任务

1.什么是Celery Celery是一个简单.灵活且可靠的,处理大量消息的分布式系统 专注于实时处理的异步任务队列 同时也支持任务调度 celery支持linux,如果windows使用celery出了问题不解决 Celery架构 Celery的架构由三部分组成,消息中间件(message broker),任务执行单元(worker)和任务执行结果存储(task result store)组成. 消息中间件 Celery本身不提供消息服务,但是可以方便的和第三方提供的消息中间件集成.包括,Ra

利用celery+django 在admin后台设置定时任务

经常用python开发web应用时,会涉及到定时任务的脚本,以前用linux自带的crontab来操作,但是感觉不太接地气,后来发现用celery+django 可以方便的实现! 安装软件环境如下: python 2.7.5 Django==1.8.2 celery==3.1.18 celery-with-redis==3.0 django-celery==3.1.16 MySQL-python==1.2.3 supervisor==3.1.3 使用pip方式安装完以上软件,并且默认系统已经安装

django+celery配置(定时任务)

下面介绍一下django+celery的配置做定时任务 1.首先介绍一下环境和版本 python==2.7 django == 1.8.1 celery == 3.1.23 django-celery == 3.1.17 2.celery的安装   sudo pip install celery==3.1.23 sudo pip install django-celery==3.1.17 3.新建一个项目 (1)django-admin startproject django_celery_de

异步任务队列Celery在Django中的使用

前段时间在Django Web平台开发中,碰到一些请求执行的任务时间较长(几分钟),为了加快用户的响应时间,因此决定采用异步任务的方式在后台执行这些任务.在同事的指引下接触了Celery这个异步任务队列框架,鉴于网上关于Celery和Django结合的文档较少,大部分也只是粗粗介绍了大概的流程,在实践过程中还是遇到了不少坑,希望记录下来帮助有需要的朋友. 一.Django中的异步请求 Django Web中从一个http请求发起,到获得响应返回html页面的流程大致如下:http请求发起 --