django+redis+celery异步任务执行

1、安装redis

参考redis文件夹下:redis安装python

文档:redis安装.note
连接: http://note.youdao.com/notesh...

2、django工程配置

一、安装依赖包

pip install celery 
pip install celery-with-redis 
pip install django-celery

二、配置

settings.py文件redis

import djcelery 

#注册jdcelery 
INSTALLED_APPS = [ 
... ,
'djcelery', 
] 
# celery 设置 
# celery中间人 redis://redis服务所在的ip地址:端口/数据库号 
BROKER_URL = 'redis://redis_ip:6379/0' 
# celery结果返回,可用于跟踪结果 CELERY_RESULT_BACKEND = 'redis://redis_ip:6379/0' 
# celery内容等消息的格式设置,这里使用pickle,若是不使用,会序列化报错 
CELERY_ACCEPT_CONTENT = ['pickle', ] CELERY_TASK_SERIALIZER = 'json' CELERY_RESULT_SERIALIZER = 'json' 

# celery时区设置,使用settings中TIME_ZONE一样的时区 CELERY_TIMEZONE = TIME_ZONE
在工程目录下,建立celery.py文件
# coding:utf-8 
from __future__ import absolute_import, unicode_literals 
from celery import Celery 
from django.conf import settings 
import os

# 获取当前文件夹名,即为该Django的项目名 
project_name = os.path.split(os.path.abspath('.'))[-1] 
project_settings = '%s.settings' % project_name 

# 设置环境变量 
os.environ.setdefault('DJANGO_SETTINGS_MODULE', project_settings)
# 实例化Celery,网上不少教程这里都是没有设置broker形成启动失败 
app = Celery('tasks', broker='redis://redis_ip:6379/0', backend='redis://redis_ip:6379/0') 

# 使用django的settings文件配置celery 
app.config_from_object('django.conf:settings') 

# Celery加载全部注册的应用 
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)
在工程目录的__init__.py文件中添加:
# 引入celery实例对象 
# 必定要添加在文件最前面,不然会报错 
from __future__ import absolute_import, unicode_literals 
from .celery import app as celery_app 
__all__ = [celery_app]
在对应app的目录下建立tasks.py文件

注意:tasks.py文件必定要建立在应用根目录下,且文件名固定,在该文件里添加你对应的后台任务代码,并注解@taskshell

import time 
from celery import task, Celery 
app = Celery('tasks', broker='redis://redis_ip:6379/0', backend='redis://redis_ip:6379/0')
#在这里添加你的后台任务方法代码,并注解task 
@task 
def add(a, b): 
    print("这是任务开始")
    c = a + b 
    print(c) 
    time.sleep(10) 
    print("这是任务结束")

三、启动celery worker

在python manage.py shell命令中输入数据库

celery -A project_name worker --pool=solo -l info

以下图,即为启动成功
clipboard.pngdjango

四、测试

在tasks.py文件中加入测试代码,这里复用上面tasks.py代码中的add方法json

在views.py文件中建立测试view方法:app

from . import tasks 

def add(request,*args,**kwargs):
    tasks.add.delay(1, 2)
    result = {'code': 0, 'msg': '这是一个后台任务'} 
    return JsonResponse(result)

在url中配置url路径测试

from django.urls import path 
from . import views 

urlpatterns = [ path('add', views.add, name="add") ]

启动djangourl

而后调用对应url,发现响应只用63ms
clipboard.pngspa

在manage.py shell日志中静候后台任务执行,发现任务已经执行,耗时10s多(由于上述代码sleep了10s)
clipboard.png
到这里,celery已成功运行。

3、问题积累

一、启动celery worker时,报连接失败

(1)多是限制bind没有注释,仅容许本机访问;参考redis配置项

(2)保护模式为关闭,参考redis配置项

(3)须要鉴权

二、运行后台任务时,报错 kombu.exceptions.ContentDisallowed: Refusing to deserialize untrusted content of type pickle (application/x-python-serialize)

https://blog.csdn.net/libing_thinking/article/details/78622943

kombu.exceptions.ContentDisallowed: Refusing to deserialize untrusted
content of type pickle (application/x-python-serialize)

须要将settings.py文件中修改celery配置

CELERY_ACCEPT_CONTENT = ['pickle', ]

三、运行后台任务时,报错AttributeError: 'str' object has no attribute 'items'

python版本为3.6

#貌似是redis版本高了,从新安装后得以解决 pip install redis==2.10.6

四、启动celery时报错:TypeError: can only concatenate tuple (not “NoneType”) to tuple

这个问题是因为安装包不全致使的,分别检查是否安装了如下安装包:

pip install celery
pip install celery-with-redis
pip install django-celery