将自己在学习celery中遇到的问题和思路记录下来,让学习更加清晰。
在使用Django进行网页的开发时,当需要用到定时任务和异步队列处理的时候,就需要用到celery。
1.本人在Ubuntu下实现的,使用pip3 install 安装celery,rabbitmq,django-celery.
2.创建一个Django项目:
django-admin startproject test
3.创建一个app: appdemo
python manage.py startapp appdemo
4.进入项目的setting文件,如下添加
import djcelery
djcelery.setup_loader()
BROKER_URL = 'redis://127.0.0.1:6379/0' #中间人,存储队列信息
CELERY_RESULT_BACKEND = 'redis://localhost:6379/1' #将结果返回到redis的1库
from datetime import timedelta
CELERY_TIMEZONE = 'Asia/Shanghai'
#CELERY_ALWAYS_EAGER = True # 如果开启,Celery便以eager模式运行, 则task便不需要加delay运行,记住没有加这个一定要再delay才是异步运行!!
CELERY_RESULT_SERIALIZER = 'json' #设置返回格式为json
CELERYBEAT_SCHEDULE = {
'add-every-3-seconds': {
'task': 'appdemo.tasks.test_celery', #运行定时任务test_celery, 要写路径为appdemo中的tasks.py,必须为tasts.py文件
'schedule': timedelta(seconds=3600), #设置循环时间
'args': (19, 16) #给定时任务的参数
},
}
5.在setting同级目录下创建 celery.py 文件和__init__.py文件中添加如下代码:
celery.py
from __future__ import absolute_import
import os
from celery import Celery, platforms
# set the default Django settings module for the 'celery' program.
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'uploadPicture.settings')
from django.conf import settings # noqa
app = Celery('uploadPicture')
platforms.C_FORCE_ROOT = True #解决celery不能用root用户启动的问题
# 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) #celery自动检索app是是否有tasks.py,有则自动创建任务
__init__.py
from __future__ import absolute_import
from .celery import app as celery_app #确保celery_app正确导入
6.在需要使用celery的模块中,添加tasks.py(django规定要命名tasks)。如在demoapp中创建tasks.py,写下celery任务:
from __future__ import absolute_import
import time
from celery import task
@task
def test_celery(x, y): #创建的任务,在setting中应用,作为定时任务
print(x + y)
return x + y #在setting中设置了CELERY_RESULT_BACKEND = 'redis://localhost:6379/1',所有把结果返回到redis中去
@task
def test_multiply(x, y):
time.sleep(10) #模拟耗时操作
print(x * y)
return x * y
7.在视图views.py中导入test_multiply,添加如下代码:def index(request):
test_multiply.delay(2,9) #加上delay才是异步执行,不然就是同步,而且如果将其赋予一个值,也是同步了
if request.method=='POST':
pass
else:
uf = pic_from()
return render(request,'index.html',{'uf':uf})
8.启动顺序为先启动django server:python manage.py runserver后启动celery worker:celery -A celery_proj worker -l info
9.启动成功从浏览器进入视图 index中,页面立刻加载成功,等10秒后,打印test_multiply中的输出