在运营系统中经常用到异步方式来处理我们的任务,比如将业务上线流程串成任务再写入队列,通过后台作业节点去调度执行。比较典型的案例为腾讯的蓝鲸、织云、云智慧等平台。本译文结合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。
1 2 |
$ pip install celery==3.1.18 $ pip freeze > requirements.txt |
现在,我们通过简单的三步将celery集成到django项目中。
步骤一:创建celery.py
在“picha“目录下,创建celery.py,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
from __future__ import absolute_import import os from celery import Celery from django.conf import settings # set the default Django settings module for the 'celery' program. os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'picha.settings') app = Celery('picha') # Using a string here means the worker will not have to # pickle the object when using 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中。
1 2 3 4 5 |
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 |
完成以上步骤后,你的项目目录应该是这样的:
1 2 3 4 5 6 7 8 |
├── manage.py ├── picha │ ├── __init__.py │ ├── celery.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py └── requirements.txt |
步骤三:安装 Redis作为Celery的“中间件”
Celery使用中间件在django项目与celery监控者之间传递消息。在本教程中,我们使用redis作为消息中间代理。
首先,从官方下载页面或通过brew(BREW安装Redis)安装Redis,然后打开你的终端上,在一个新的终端窗口,启动服务器:
1 |
$ redis-server |
你可以通过在终端中输入如下命令测试Redis是否正常工作。
1 |
$ redis-cli ping |
Redis应该回复PONG – 试试吧!
一旦Redis正常启动了,把下面的代码添加到你的settings.py文件中:
1 2 3 4 5 6 7 |
织云、云智慧等平台。本译文结合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标签
二、什么是Celery“Celery是一个异步任务队列/基于分布式消息传递的作业队列。它侧重于实时操作,但对调度的支持也很好。”本文,我们将重点讲解周期性执行任务的调度特点。 为什么这一点有用呢? 回想一下你不得不在将来运行某一特定任务的经历。也许你需要每隔一小时访问一个API。或者,也许你需要在这一天结束时发送一批电子邮件。不论任务大小,Celery都可以使得调度周期性任务变的很容易。 你永远不希望终端用户等待那些不必要的页面加载或动作执行完成。如果你的应用程序工作流的一部分是一个需要很长时间的程序,当资源可用时,你就可以使用Celery在后台执行这段程序,从而使你的应用程序可以继续响应客户端的请求。这样可以使任务在应用程序的环境之外运行。
三、构建项目在深入了解Celery之前,先从Github库中获取开始项目。确保激活一个虚拟的环境,安装必要的软件,并运行迁移。然后启动服务器,通过你的浏览器导航到http://localhost:8000/。你应当能看到‘恭喜你的第一个Django页面’。完成后,关闭服务器。
现在,我们通过简单的三步将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 – 试试吧! |