首先简单介绍一下,Celery 是一个强大的分布式任务队列,它可以让任务的执行完全脱离主程序,甚至可以被分配到其他主机上运行。我们通常使用它来实现异步任务(async task)和定时任务(crontab)。
如果你觉得自己的django项目有些行为逻辑实在没必要耽误在页面跳转上时,一方面可以用Ajax异步提交来避免,而我更推荐用celery来做异步处理。
注意:Celery 本身不提供队列服务,官方推荐使用 RabbitMQ 和 Redis 等。
使用 Celery 实现异步任务主要包含三个步骤:
- 创建一个 Celery 实例
- 启动 Celery Worker
- 应用程序调用异步任务
一、环境搭建
假设目前在Ubuntu系统环境下,我们采用redis作为消息中间件,需要安装以下依赖:
pip install django==1.9 安装django
pip install celery==4.0 安装celery(听说最近的4.0版本直接支持django了)
sudo apt install redis
二、配置celery
首先,假设你的django目录如下
project
--manage.py
--project
--settings.py
--wsgi.py
--urls.py
--__init__.py
--__pycache__
--db.sqlite3
那么,在settings.py中配置如下代码:
CELERY_BROKER_URL = 'redis://localhost'
CELERY_ACCEPT_CONTENT = ['json']
CELERY_RESULT_BACKEND = 'redis://localhost'
CELERY_TASK_SERIALIZER = 'json'
三、添加异步模块
1、在settings.py的根目录下,新建一个celery.py文件,添加代码:
from __future__ import absolute_import, unicode_literals
import os
from celery import Celery
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'project.settings')
#实际上这里填入的是你项目的settings路径
app = Celery('project')
# 这里的‘project’是你的项目名称
app.config_from_object('django.conf:settings', namespace='CELERY')
#namespace='CELERY'表示,所有与celery相关的配置都以'CELERY'为前缀
# 从所有已注册的Django app配置中加载任务模块
app.autodiscover_tasks()
2、随后在你的APP目录下,新建一个task.py文件:
import time
from celery import Celery
celery_app = Celery('tasks', backend='redis://localhost', broker='redis://localhost')
# this is celery settings
# this is a function about need many time
@celery_app.task
def add(a, b):
time.sleep(5)
return a + b
这样就完成一个简单的异步处理了
四、运行测试
首先在打开一个终端,开启redis,在终端输入redis-server
,见到如下图示就是成功了:
_.-``__ ''-._
_.-`` `. `_. ''-._ Redis 4.0.9 (00000000/0) 64 bit
.-`` .-```. ```\/ _.,_ ''-._
( ' , .-` | `, ) Running in standalone mode
|`-._`-...-` __...-.``-._|'` _.-'| Port: 6379
| `-._ `._ / _.-' | PID: 5433
`-._ `-._ `-./ _.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' | http://redis.io
`-._ `-._`-.__.-'_.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' |
`-._ `-._`-.__.-'_.-' _.-'
`-._ `-.__.-' _.-'
`-._ _.-'
`-.__.-'
之后新建终端,执行命令 python manage.py runserver
,之后再新建一个终端,执行命令 celery -A project worker -l info
(注: 此处的project为Django项目名称),没有看到报错的话,就证明运行成功了。
终端日志中可以发现,在访问网址5秒之后,自定义的 add 函数运行完成,并没有阻塞我们的访问响应。