对于开发人员,尤其要注重用户体验,毕竟没有用户使用,那么开发将毫无意义。
Celery异步处理框架,可用于执行耗时任务,比如发送邮件、文件上传,图像处理等等比较耗时的操作,这样用户不需要等待很久,可大大提高用户体验。
一、Celery介绍
-
简介
Celery 是一个简单、灵活且可靠的,处理大量消息的分布式系统,并且提供维护这样一个系统的必需工具。它是一个专注于实时处理的任务队列,同时也支持任务调度。
Celery 有广泛、多样的用户与贡献者社区。
Celery 是开源的,使用 BSD 许可证 授权。
-
优点
简单:配置项目少,在项目中直接导入使用灵活:celery的很多组件都支持灵活拓展
高可用:当任务执行失败后,它会自动重新执行
快速:单进程的celery每秒执行上百万个任务
二、Celery配置
因为电脑上有原来安装的
redis
数据库,所以我们使用redis的作为celery任务队列;
传送门:Windows和Linux(Centos7)下的Redis安装及使用
项目和app创建不过多说明,直接进入主题
-
安装依赖包
pip install celery pip install django-celery pip install redis
-
settings.py
配置# celery中间人 redis://redis ip地址:端口/数据库号 BROKER_URL = 'redis://localhost:6379/1' # celery结果返回,可用于跟踪结果 CELERY_RESULT_BACKEND = 'redis://localhost:6379/1' # celery内容等消息的格式设置 CELERY_ACCEPT_CONTENT = ['application/json', ] CELERY_TASK_SERIALIZER = 'json' CELERY_RESULT_SERIALIZER = 'json' # celery时区设置,使用settings中TIME_ZONE同样的时区 CELERY_TIMEZONE = TIME_ZONE
-
在
settings.py
的同级目录下创建celery.py
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 app = Celery(project_name) # 使用django的settings文件配置celery app.config_from_object('django.conf:settings') # Celery加载所有注册的应用 app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)
第一行导入不能换位置,只能在首行,否则会报错
-
为方便导入,把实例化celery的app放到
__init__.py
里(settings.py同级目录下的__init__.py
)from __future__ import absolute_import, unicode_literals # 引入celery实例对象 from .celery import app as celery_app
-
根目录(
manage.py
同级目录)下创建celery_tasks
目录,然后在celery_tasks
目录下创建tasks.py
(此文件名必须是tasks
),并把耗时任务写进去from celery_test import celery_app #celery_test为我的项目名 from app1 import models #app1为我的app名 import time from celery import platforms platforms.C_FORCE_ROOT = True @celery_app.task def login_ip(ip): models.Login_ip.objects.create(ip=ip) time.sleep(10) print('登录ip存储成功')
-
在view中调用
from django.shortcuts import render from celery_tasks.tasks import login_ip # Create your views here. def index(request): ip = '127.0.0.1' login_ip.delay(ip) #异步调用 return render(request, 'index.html')
注:使用
.delay()
进行异步调用 -
以上配置完成后项目目录结构如下
├──celery_test ├── celery_test │ ├── __init__.py │ ├── asgi.py │ ├── celery.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── app1 │ ├── migrations │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── models.py │ └── views.py ├── celery_tasks │ └── tasks.py ├── templates │ └── index.html └── manage.py
三、启动celery
必须先启动redis服务,安装和简单使用请参考:Windows和Linux(Centos7)下的Redis安装及使用
方法一:在managy同级文件目录下,输入命令(celery_test
为我的项目名):
celery -A celery_test worker -l info
下列形式说明启动正常
(venv) F:\celery_test>celery -A celery_test worker -l info
......
DEBUG leads to a memory leak, never use this setting in production environments!
warnings.warn('Using settings.DEBUG leads to a memory leak, never '
[2019-12-21 19:14:28,550: WARNING/MainProcess] celery@DESKTOP-ORHB3U3 ready.
方法二:守护进程方式启动,日志记录在celerylog.log里(celery_test
为我的项目名):
celery multi start w1 -A celery_test -l info --logfile = celerylog.log --pidfile = celerypid.pid
停止:celery multi stop w1 -A celery_test -l info
重启:celery multi restart w1 -A celery_test -l info
启动过程中可能会出现的报错
- 报错(/etc/init.d/redisd: line 28: /usr/local/bin/redis-server: No such file or directory)的解决办法
- 解决不能用root用户启动Celery Worker的问题
- 报错(AttributeError: ‘str’ object has no attribute ‘items’)的解决办法
- 报错(SQLite 3.8.3 or later is required (found 3.7.17).)的解决办法
四、启动Django项目
正常启动即可:python manage.py runserver
如大家发现问题,欢迎留言交流