celery在Django中的集成使用
继上回安装和使用Redis之后,看看如何在Django中使用Celery。Celery是Python开发分布式任务列队的处理库。可以异步分布式地异步处理任务,也可定时执行任务等等。通常我们可以在Django执行一些比较耗时的任务(例如发邮件)和后台任务(例如爬虫和更新服务器缓存)。
研究发现,在Django中使用有两种方式:
1)使用django-celery应用;
2)直接使用Celery。
1、Celery方式的选择
这里Celery的中间人,我采用Redis。也可以用Django自身和mongodb等。Celery的中间人你可以理解为在Celery执行过程中的数据支持。保存列队记录、执行记录等等。安装Redis,可参考Redis在CentOS和Windows安装过程。
这里还需要安装celery-with-redis,执行命令:
- pip install celery-with-redis
该命令会自动安装redis、celery、kombu、billiard、amqp、vine和celery-with-redis相关库。
先说说django-celery的方式吧。这种方式就是通过manage.py启动celery。通常先被提到的方案是不会采用。用pip安装django-celery,在settings引用djcelery应用。再更新数据库:
- python manage.py makemigrations djcelery
- python manage.py migrate djcelery
查看数据库,会发现多了很多相关的表。

稍稍有些强迫症的我,不能接受这些表脏我的数据库。另外djcelery还有个用途是在admin后台动态添加定时任务。这个功能也是比较鸡肋,维护不方便而且可能造成各种不可预知的问题。
所以建议直接使用Celery管理Django中的任务。这种方式也是Celery官网推荐的方式,可看官网的示例:Celery官网(Celery 3.x版)
2、Django简单项目准备
这里我也简单做一个示例。
首先,确保celery和redis已经安装好了,并且已经启动了Redis服务。
另外,有个已经搭建好了Django项目。作为示例,简单project和简单app如下:
为了测试,一切从简。views.py写了一个响应方法:
#coding:utf-
from django.shortcuts import render
from django.http import HttpResponse from .models import Blog
import json def home(request):
data = list(Blog.objects.values('caption'))
return HttpResponse(json.dumps(data), content_type = 'application/json')
django项目的urls.py加了一条首页的url路由设置:
#coding:utf-
from django.conf.urls import url
from django.contrib import admin
from myapp. urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^$', 'myapp.views.home', name='home')
]
运行django项目:
python manage.py runserver
3、Django加入Celery
现打开首页要执行一个收集访客数据,发送邮件等操作。这是一个耗时任务,若放在home处理方法中执行,用户打开首页会很慢。用户体验不好,很可能不会等到页面打开。
通常这个耗时任务可以多线程处理或者异步处理。我们模拟一个耗时任务,丢给Celery异步处理。
先模拟耗时任务,打开views.py,修改如下:
#coding:utf-
from django.shortcuts import render
from django.http import HttpResponse from .models import Blog
import json
import time def sendmail(email):
print('start send email to %s' % email)
time.sleep() #休息5秒
print('success')
return True def home(request):
#耗时任务,发送邮件
sendmail('test@test.com') #其他行为
data = list(Blog.objects.values('caption'))
return HttpResponse(json.dumps(data), content_type = 'application/json')
如此一来,至少需要再多等待5秒,才可以打开网页。
打开settings.py所在的文件夹,新建celery.py文件。加入如下代码(注意,因为celery-with-django版本限制,我安装的celery版本为3.1.25。可能celery4.x的版本代码不同):
#coding:utf-
from django.shortcuts import render
from django.http import HttpResponse from .models import Blog
import json
import time def sendmail(email):
print('start send email to %s' % email)
time.sleep() #休息5秒
print('success')
return True def home(request):
#耗时任务,发送邮件
sendmail('test@test.com') #其他行为
data = list(Blog.objects.values('caption'))
return HttpResponse(json.dumps(data), content_type = 'application/json')
这个文件还没被加载,接着打开settings.py同个目录下的__init__.py文件。让运行该Django项目的时候,加载该文件配置Celery。修改代码如下:
#coding:utf-
from __future__ import absolute_import, unicode_literals #引入celery实例对象
from .celery import app as celery_app
还需在settings.py中设置celery,尤其是中间人的设置。若不设置中间人,会提示无法连接中间人的错误。在settings.py文件中添加如下设置:
#celery settings
#celery中间人 redis://redis服务所在的ip地址:端口/数据库号
BROKER_URL = 'redis://localhost:6379/0'
#celery结果返回,可用于跟踪结果
CELERY_RESULT_BACKEND = 'redis://localhost:6379/0' #celery内容等消息的格式设置
CELERY_ACCEPT_CONTENT = ['application/json',]
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json' #celery时区设置,使用settings中TIME_ZONE同样的时区
CELERY_TIMEZONE = TIME_ZONE
4、把耗时任务丢给celery处理
上面views.py中有个耗时任务sendmail。在myapp应用中新建文件tasks.py,将sendmail方法剪切到该文件中并用定义为celery任务。tasks.py文件如下代码:
#coding:utf-
from celery.decorators import task
import time @task
def sendmail(email):
print('start send email to %s' % email)
time.sleep() #休息5秒
print('success')
return True
在原有的方法上加上celery装饰器task。或者也可以通过前面添加的celery_app给sendmail方法加装饰器:
#coding:utf-
#myproject是当前django的项目名
from myproject import celery_app
import time @celery_app.task
def sendmail(email):
print('start send email to %s' % email)
time.sleep() #休息5秒
print('success')
return True
另外原先的views.py修改如下:
#coding:utf-
from django.shortcuts import render
from django.http import HttpResponse from .models import Blog
from .tasks import sendmail #引用tasks.py文件的中sendmail方法
import json def home(request):
#耗时任务,发送邮件(用delay执行方法)
sendmail.delay('test@test.com') #其他行为
data = list(Blog.objects.values('caption'))
return HttpResponse(json.dumps(data), content_type = 'application/json')
5、本地启动celery并测试
启动celery之前,确保已经安装redis和启动redis服务,可参考Redis在CentOS和Windows安装过程。
本地开发环境运行redis-cli看是否可以正常连接,若不行,再手工执行redis-server命令并保持窗口即可。
接着,启动celery worker。这个worker是用于异步执行任务的“工作者”。进入manage.py文件所在的目录,执行如下命令:
Celery -A myproject worker -l info
出现如下窗口和消息,则正常执行。

celery worker会扫描django项目中有哪些task任务,并加入进来。
最后,再启动django服务器。这个大家熟悉的python manage.py runserver。
打开首页,可以发现没有5秒等待立即得到首页内容。查看celery worker,可看到执行sendmail方法的消息。
celery在Django中的集成使用的更多相关文章
- Celery在Django中的使用介绍
Celery在Django中的使用介绍 Celery简介 celery是一个简单.灵活且可靠的,处理大量消息的分布式系统,并且提供维护这样一个系统的必须工具. 它是一个专注于实时处理的任务队列,同时也 ...
- 异步任务队列Celery在Django中的使用
前段时间在Django Web平台开发中,碰到一些请求执行的任务时间较长(几分钟),为了加快用户的响应时间,因此决定采用异步任务的方式在后台执行这些任务.在同事的指引下接触了Celery这个异步任务队 ...
- celery在Django中的应用
这里不解释celery,如果不清楚可以参考下面链接: http://docs.celeryproject.org/en/latest/getting-started/introduction.html ...
- Django 中使用 Celery
起步 在 <分布式任务队列Celery使用说明> 中介绍了在 Python 中使用 Celery 来实验异步任务和定时任务功能.本文介绍如何在 Django 中使用 Celery. 安装 ...
- Django中Celery的实现介绍(一)
Django中Celery的实现 Celery官网http://www.celeryproject.org/ 学习资料:http://docs.jinkan.org/docs/celery/ Cele ...
- Django中使用Celery
一.前言 Celery是一个基于python开发的分布式任务队列,如果不了解请阅读笔者上一篇博文Celery入门与进阶,而做python WEB开发最为流行的框架莫属Django,但是Django的请 ...
- 分布式队列celery 异步----Django框架中的使用
仅仅是个人学习的过程,发现有问题欢迎留言 一.celery 介绍 celery是一种功能完备的即插即用的任务对列 celery适用异步处理问题,比如上传邮件.上传文件.图像处理等比较耗时的事情 异步执 ...
- Django中使用Celery,定制应用程序中定义的shared_task未在定期任务管理页面的注册任务中显示
解决办法: 在项目 proj/proj/celery.py文件中,看到下面这行配置: celery_app.config_from_object('django.conf:settings', nam ...
- Django中Celery http请求异步处理(四)
Django中Celery http请求异步处理 本章延续celery之前的系列 1.settings配置 2.编写task jib_update_task任务为更新salt jid数据 3.url设 ...
随机推荐
- svn断开链接后,重新share提交代码报错
前言:svn怎样断开链接并清除干净请查看此地址-->android studio中断开SVN连接,并彻底清理项目中的.svn文件 1.每次把项目重新关联到新的svn地址上,我都抓狂一样的烦躁,因 ...
- git<撤销本地修改与回退版本>
1. 使用 git checkout 撤销本地修改 即放弃对本地已修改但尚未提交的文件的修改,还原其到未修改前的状态. 注意: 已 add/ commit 的文件不适用个方法,应该用本文提到的第二种方 ...
- Unity ZTest深度测试 & ZWrite深度写入
Shader深度渲染队列Queue预定义值:Background(1000).Geometry(2000).AlphaTest(2450).Transparent(3000).Overlay(4000 ...
- Docker Swarm应用--lnmp部署WordPress
一.简介 目的:使用Docker Swarm 搭建lnmp来部署WordPress 使用Dockerfile构建nginx.php镜像 将构建的镜像上传docker私有仓库 使用volume做work ...
- Android的taskAffinity对四种launchMode的影响
在Android系统中,一个application的所有Activity默认有一个相同的affinity(亲密关系,相似之处).也就是说同一个应用程序的的所有Activity倾向于属于同一个task. ...
- NGINX生产环境反向代理到后端tomcat配置
#当访问www.kazihuo.com//sichuan-user-te时,跳转到http://10.1.93.61:7005/sichuan-user server { listen ; serve ...
- angularJS 事件广播与接收
发送消息: $scope.$emit(name, data) 或者 $scope.$broadcast(name, data); 接收消息: $scope.on(name,function(event ...
- spring-boot添加自定义拦截器
spring-boot中的WebMvcConfigurerAdapter类提供了很多自定义操作的方法,先贴出来大家看看 package org.springframework.web.servlet. ...
- 【学习笔记】初识FreeMarker简单使用
楔子: 之前在和同事讨论,同事说“jsp技术太古老了,有几种页面技术代替,比如FreeMarker.Velocity.thymeleaf,jsp快废弃了……”云云.我这一听有点心虚……我在后端部分越刨 ...
- Linux下压缩文件-2
Linux下的压缩文件剖析 对于刚刚接触Linux的人来说,一定会给Linux下一大堆各式各样的文件名给搞晕.别个不说,单单就压缩文件为例,我们知道在Windows下最常见的压缩文件就只有两种,一是, ...