前言:随着项目并发量的增加,怎样去提高项目的效率是我们不能不去考虑的事情,所有使用消息队列技术,将耗费时间的任务放到队列中做异步执行是非常好的一个策略,本文以django为例来说明celery的配置。
celery的介绍
- 首先介绍一下celery
Celery 是一个简单、灵活、可靠的分布式系统,可处理大量消息,同时为操作提供维护此类系统所需的工具。它是一个专注于实时处理的任务队列,同时也支持任务调度。
- celery结构
celery主要分为三个部分【客户端,broker,worker】,对于broker , celery支持使用支持如下的第三方工具(官方建议的是RabbitMQ,但是本文介绍的是使用Redis来实现celery):
开始配置
- 启动Redis
首先要安装redis,安装教程请自行查找,此文不做概述。
- 在redis目录下,输入cmd进入Dos窗口(必须Dos窗口要进入redis安装目录下):
- 输入命令启动redis:redis-server.exe redis.windows.conf (Windows版本下命令,其它版本请自行百度)
- 安装对应的库
以下是我的各库的版本:
Django : 3.2
Python : 3.7
Celery : 5.0.5
Redis : 3.5.3
一个小小的提醒:
1:安装时(还有后边的启动celery时)会出现各种匪夷所思的报错,各位加油吧,总之一句话:“遇到问题先看报啥错,千万别直接去搜,大家谨记”
2:遇到库的版本问题,提示那个库版本不对,换提示要求的那个库版本就好
安装:
pip install celery==5.0.5
pip install redis==3.5.3
- 配置Celery
- 首先让我们来看一下整个的目录(接下来我们一步一步的配置)
- 新建一个包,名字随便起,我的名字叫celery_tasks。其次在该文件下创建两个文件,这两个文件的文件名是固定的不能修改,分别为:config.py 和 main.py
注意:这个包一定要和启动文件在同一个目录下
- 回到主目录,在setting中配置一下redis的连接参数
REDIS_DATABASE = {
# 配置的是队列执行结果存储的参数
'CELERY_BACKEND': {
'DB': '5', # 随意一个库
'HOST': '127.0.0.1',
'PASSWORD': '123456', # redis的密码
'POST': '6379'
},
# 配置的是存储队列的参数
'CELERY_BROKER': {
'DB': '1', # 随意一个库
'HOST': '127.0.0.1',
'PASSWORD': '123456', # redis的密码
'POST': '6379'
}
}
- 配置main.py这个文件
from celery import Celery
import os
from django.conf import settings
# 读取Django的配置
"""
DRF.settings:
是settings这个文件的目录,一定要看好,我的主文件叫DRF所以我的目录是DRF.settings)
"""
os.environ["DJANGO_SETTINGS_MODULE"] = "DRF.settings"
# "redis://127.0.0.1:6379/1",只要在settings中配置好连接参数则下方直接复制就好
redis_database = settings.REDIS_DATABASE['CELERY_BACKEND']
backend = f'redis://:{redis_database["PASSWORD"]}@{redis_database["HOST"]}:{redis_database["POST"]}/{redis_database["DB"]}'
app = Celery("meiduo", backend=backend)
# app = Celery("meiduo")
# celery项目配置: worker代理人,指定任务存储到哪里区。
# celery_tasks是我们刚刚建的文件名
app.config_from_object('celery_tasks.config')
# 加载可用的任务,这个先不急,我们下方会说到
app.autodiscover_tasks([
'celery_tasks.sms'
])
- 配置config.py文件
from django.conf import settings
# 代理人:指定redis作为消息队列
redis_database = settings.REDIS_DATABASE['CELERY_BROKER']
backend = f'redis://:{redis_database["PASSWORD"]}@{redis_database["HOST"]}:{redis_database["POST"]}/{redis_database["DB"]}'
broker_url = backend
- 开始创建任务模块
首先在我们的celery目录下创建一个文件夹(包),名字随便起
- 在该文件下再创建一个文件,此文件的名字是固定的,叫:tasks.py
- tasks.py配置
# 导入main中的app
from celery_tasks.main import app
from time import sleep
@app.task
def send(a, b):
# 具体要执行的任务
print("开始")
print(a, b)
sleep(4)
print("结束")
return 1
- 将任务加入到任务列表中,在main.py这个文件中
到此时所有的配置工作就完成了,接下来我们启动celery
- 启动celery
-
进入终端,此时要注意一个问题,终端中,目录一定要在项目的目录下,不能进入celery目录
-
命令启动
-
如果你是max / linux系统,则直接输入:celery -A celery_tasks.main worker -l info
-
如果你是windows系统(我是windows系统),则输入:celery -A celery_tasks.main worker --pool=solo -l info
- 写一个接口去调用任务
在其它的APP中直接正常写接口就好。
- 测试一下:
请求完成:
接下来我们再看看celery的执行:
很明显已经执行完成,接下来我们看看redis中数据,因为我们的任务已经执行完成,所以在队列中已经没有数据了。
再看一下结果。结果已经写入了redis:
- 获取任务的执行结果
此处我就不再写接口测试了,直接放一下获取结果的方法:
from celery.result import AsyncResult
from celery_tasks.sms.tasks import send
class GetSendSmsView(APIView):
def get(self, request):
data = request.query_params # 接收任务的id(就是刚刚我们返回的那个)
asy = AsyncResult(id=data['id'], app=app)
if asy.successful():
res = asy.get()
print('任务执行结果:', res)
elif asy.failed():
print('任务失败')
elif asy.status == 'PENDING':
print('任务等待中被执行')
elif asy.status == 'RETRY':
print('任务异常后正在重试')
elif asy.status == 'STARTED':
print('任务已经开始被执行')
return Response({})
以上就是Django配置Celery的全部过程了!
【文章编写不易,如需转发请联系作者!】