一个Django与Celery实现异步队列任务定时任务教程

本文根据以下文章讲解Django与Celery如何实现异步队列任务:

    http://python.jobbole.com/81953/

    https://realpython.com/blog/python/asynchronous-tasks-with-django-and-celery/

之所以要写这篇文章原因:

        1. 该文章有一些错误,会导致程序无法运行。

        2. 部分步骤说的不是很细,对于第一次接触celery的人来说,会有一点懵逼。

本项目利用python3.5、Django 1.11.2、Celery3.1.18和Redis3.2.1

一、概述

由于大篇幅的文字,为了您的方便,请参阅下表中的每一步的简要信息,并获取相关的代码。

步骤                 概要                                     Git标签
样板                 样板下载                                 V1
建立                 集成Celery和Django              V2
Celery任务      添加基本的Celery任务             V3
周期性任务      添加周期性任务                       V4
本地运行         本地运行我们的应用程序          V5
远程运行         远程运行我们的应用程序          V5

二、什么是Celery

“Celery是一个异步任务队列/基于分布式消息传递的作业队列。它侧重于实时操作,但对调度的支持也很好。”本文,我们将重点讲解周期性执行任务的调度特点。

为什么这一点有用呢?

回想一下你不得不在将来运行某一特定任务的经历。也许你需要每隔一小时访问一个API。或者,也许你需要在这一天结束时发送一批电子邮件。不论任务大小,Celery都可以使得调度周期性任务变的很容易。

你永远不希望终端用户等待那些不必要的页面加载或动作执行完成。如果你的应用程序工作流的一部分是一个需要很长时间的程序,当资源可用时,你就可以使用Celery在后台执行这段程序,从而使你的应用程序可以继续响应客户端的请求。这样可以使任务在应用程序的环境之外运行。

三、构建项目

在深入了解Celery之前,先从Github库中获取开始项目。确保激活一个虚拟的环境,安装必要的软件,并运行迁移。然后启动服务器,通过你的浏览器导航到http://localhost:8000/。你应当能看到‘恭喜你的第一个Django页面’。完成后,关闭服务器。
接下来,我们开始安装celery。

pip install celery==3.1.18

现在,我们通过简单的三步将celery集成到django项目中。

步骤一:创建celery.py

在“picha“目录下,创建celery.py,代码如下:

from __future__ import absolute_import
import os
from celery import Celery
from django.conf import settings

# 为Celer程序设置默认的Django设置模块
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'picha.settings')
app = Celery('picha')

# 在这里使用一个字符串表示工作人员在使用Windows时不必序列化对象。
app.config_from_object('django.conf:settings')
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)


@app.task(bind=True)
def debug_task(self):
    print('Request: {0!r}'.format(self.request))

请注意代码中的注释。

步骤二:引入celery应用

为了确保在django启动时加载了celery应用,在settings.py旁边新建__init__.py,并添加以下代码到__init__.py中。

from __future__ import absolute_import

# 这将确保在Django启动时始终导入应用程序,以便shared_task将使用此应用程序。
from .celery import app as celery_app

完成以上步骤后,你的项目目录应该是这样的:

├── manage.py 
├── picha 
│   ├── __init__.py 
│   ├── celery.py 
│   ├── settings.py 
│   ├── urls.py 
│   └── wsgi.py 
└── requirements.txt

步骤三:安装 Redis作为Celery的“中间件”

Celery使用中间件在django项目与celery监控者之间传递消息。在本教程中,我们使用redis作为消息中间代理。

Redis安装教程和使用教程请参考文章:http://www.chenxm.cc/post/287.html

首先,从官方下载页面或通过brew(BREW安装Redis)安装Redis,然后打开你的终端上,在一个新的终端窗口,启动服务器:

redis-server

你可以通过在终端中输入如下命令测试Redis是否正常工作。

>redis-cli ping
PONG

Redis应该回复PONG – 试试吧!
一旦Redis正常启动了,把下面的代码添加到你的settings.py文件中:

# CELERY STUFF 
BROKER_URL = 'redis://localhost:6379' 
CELERY_RESULT_BACKEND = 'redis://localhost:6379' 
CELERY_ACCEPT_CONTENT = ['application/json'] 
CELERY_TASK_SERIALIZER = 'json' 
CELERY_RESULT_SERIALIZER = 'json' 
CELERY_TIMEZONE = 'Africa/Nairobi'

你还需要添加Redis的作为Django项目的依赖:

pip install redis==2.10.3

就是这样了!你现在应该能够在Django中使用Celery。有关设置Celery与Django的更多信息,请查看官方Celery文档。

在继续下面步骤之前,让我们进行一些完整性检查,以确保一切都是正常的。

测试Celery worker已准备好接收任务:

I:\djangoew_picha>celery -A new_picha worker -l info

 -------------- celery@DESKTOP-PVV9EBS v3.1.18 (Cipater)
---- **** -----
--- * ***  * -- Windows-10-10.0.10586-SP0
-- * - **** ---
- ** ---------- [config]
- ** ---------- .> app:         picha:0x20b6c783da0
- ** ---------- .> transport:   redis://localhost:6379//
- ** ---------- .> results:     redis://localhost:6379
- *** --- * --- .> concurrency: 8 (prefork)
-- ******* ----
--- ***** ----- [queues]
 -------------- .> celery           exchange=celery(direct) key=celery


[tasks]
  . new_picha.celery.debug_task

[2017-08-29 09:32:32,406: INFO/MainProcess] Connected to redis://localhost:6379//
[2017-08-29 09:32:33,425: INFO/MainProcess] mingle: searching for neighbors
[2017-08-29 09:32:36,433: INFO/MainProcess] mingle: all alone
[2017-08-29 09:32:41,453: WARNING/MainProcess] d:\software\python35\lib\site-packages\celery\fixups\django.py:265: UserWarning: Using settings.DEBUG leads to a memory leak, never use this setting in production environments!
  warnings.warn('Using settings.DEBUG leads to a memory leak, never '
[2017-08-29 09:32:41,455: WARNING/MainProcess] celery@DESKTOP-PVV9EBS ready.

使用CTRL-C杀死该段程序。现在,测试Celery任务调度程序是否已经准备好:

I:\djangoew_picha>celery -A new_picha beat -l info
celery beat v3.1.18 (Cipater) is starting.
__    -    ... __   -        _
Configuration ->
    . broker -> redis://localhost:6379//
    . loader -> celery.loaders.app.AppLoader
    . scheduler -> celery.beat.PersistentScheduler
    . db -> celerybeat-schedule
    . logfile -> [stderr]@%INFO
    . maxinterval -> now (0s)
[2017-08-29 09:33:48,048: INFO/MainProcess] beat: Starting...

在上述完成时再次终止该进程。

celery命令总结:

$ celery -A picha worker -l info     #Celery worker接收任务启动
$ celery -A picha beat -l info       #Celery 任务调度程序启动

使用注意:

        必须要在项目文件夹下的cmd中输入该命令,否则会提示ImportError: No module named 'new_picha'错误

相关文章

文章浏览阅读1.3k次。在 Redis 中,键(Keys)是非常重要的概...
文章浏览阅读3.3k次,点赞44次,收藏88次。本篇是对单节点的...
文章浏览阅读8.4k次,点赞8次,收藏18次。Spring Boot 整合R...
文章浏览阅读978次,点赞25次,收藏21次。在Centos上安装Red...
文章浏览阅读1.2k次,点赞21次,收藏22次。Docker-Compose部...
文章浏览阅读2.2k次,点赞59次,收藏38次。合理的JedisPool资...