基于Django与Celery实现异步队列任务

482 查看

在运营系统中经常用到异步方式来处理我们的任务,比如将业务上线流程串成任务再写入队列,通过后台作业节点去调度执行。比较典型的案例为腾讯的蓝鲸、织云、云智慧等平台。本译文结合Django+Celery+Redis实现一个定期从Flickr 获取图片并展示的简单案例,方便大家理解实现异步对列任务的过程。

刚接触django的时候,我经历过的最让人沮丧的事情是需要定期运行一段代码。我写了一个需要每天上午12点执行一个动作的不错的函数。很简单是不是?错了。事实证明,这对我来说是一个巨大的困难点,因为,那时我使用Cpane类型的虚拟主机管理系统,它能专门提供一个很友好,很方便的图形用户界面来设置cron作业。

经过反复研究,我发现了一个很好的解决方案 – Celery,一个用于在后台运行任务的强大的异步作业队列。但是,这也导致了其它的问题,因为我无法找到一系列简单的指令将celery集成到Django项目中。

当然,我最终还是设法成功搞定了它 – 这正是本文将介绍的内容:如何将celery集成到一个Django项目,创建周期性任务。

该项目利用Python3.4,Django的1.8.2,celery3.1.18和Redis3.0.2.

 

一、概述

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

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

 

二、什么是Celery

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

为什么这一点有用呢?

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

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

 

三、构建项目

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

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

步骤一:创建celery.py

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

请注意代码中的注释。

步骤二:引入celery应用

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

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

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

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

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

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

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