参考的博客
(大江狗)pythondjango.cn/
一些更详细的配置之类的建议从这里查看
安装的包与版本
celery==5.0.5
redis==3.5.3
# 需要设置定时或周期任务时安装
django-celery-beat==2.2.0
# 视情况需要,需要存储任务结果时安装,视情况需要,假如将存储任务结果储存在redis上的话,则不用安装
# 本文将结果存储位置在redis上,不进行安装
django-celery-results==2.0.1
配置项
首先创建了项目,名为forumend
,那么需要在forumend/forumend
(也就是和settings.py
同目录)
目录下 :
添加文件celery.py
并修改init.py
文件:
celery.py
import os
from celery import Celery
""" 设置环境变量
forumend.settings就是forumend/forumend下的settings.py文件 """
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'forumend.settings')
""" 实例化 """
app = Celery('forumend')
""" namespace='CELERY'作用是允许你在Django配置文件中对Celery进行配置
但所有Celery配置项必须以CELERY开头,防止冲突 """
app.config_from_object('django.conf:settings', namespace='CELERY')
""" 自动从Django的已注册app中发现任务 """
app.autodiscover_tasks()
init.py
from .celery import app as celery_app
__all__ = ('celery_app',)
另外还要对settings.py进行配置
在总的配置文件setings.py进行配置 ,这里针对celery中的broker
和存储结果位置
进行配置
settings.py
""" 最重要的配置,设置 消息broker 以及 结果存储位置backend ,
格式为:db://user:password@host:port/dbname
如果redis安装在本机,使用localhost或127.0.0.1 :端口/数据库号
如果docker部署的redis,使用redis://redis:6379
下面将消息存储在redis 0号数据库上,将结果存储在redis 1号数据库上
本来应该是BROKER_URL,但是由于在celery.py中配置了
app.config_from_object('django.conf:settings', namespace='CELERY')\
由于namesapce的作用,配置项前面要加上CELERY_,最终变成 CELERY_BROKER_URL
"""
CELERY_BROKER_URL = "redis://127.0.0.1:6379/0"
CELERY_RESULT_BACKEND = 'redis://127.0.0.1:6379/1'
""" celery时区设置,建议与Django settings中TIME_ZONE同样时区,防止时差
Django设置时区需同时设置USE_TZ=True和TIME_ZONE = 'Asia/Shanghai' """
CELERY_TIMEZONE = TIME_ZONE
同时在settigns.py
的已有配置上修改:USE_TZ=True
和TIME_ZONE = 'Asia/Shanghai'
执行异步任务
新建一个子应用,名为user
创建任务
在子应用下创建文件tasks.py
tasks.py
from celery import shared_task
import time
"""
这里的任务返回数据到时候会返回到reids 1号数据库中
注意:
一般在app下面创建的任务,其任务的装饰器一般使用@shared_task
但是假如任务不在app下面而是在主项目的目录下或其他位置,一般使用@app.task
"""
@shared_task
def add(x, y):
time.sleep(2)
return x + y
创建视图,路由
views.py
from .tasks import add
from celery.result import AsyncResult
import time
class CeleryTest(APIView):
def get(self,request):
# 方式一:异步调用该任务,表示为add运行,参数为3,5,既为add(3,5)
# add.delay(3, 5)
# return HttpResponse("Celery works")
# 方式二:使用apply_async可以接收更多的参数
async_task = add.apply_async(args=[3, 5])
# 获取任务状态和结果
status = AsyncResult(async_task.task_id).status
result = AsyncResult(async_task.task_id).result
" 结果分别为:PENDING None,这是因为视图比任务先执行完。状态以及结果都为不确定? "
print(status)
print(result)
return HttpResponse("Celery works")
user/urls.py
re_path('^cete$',views.CeleryTest.as_view())
运行并查看结果
1.启动项目
python manage.py runserver
2.打开另一个终端运行worker(注意需要提前打开redis数据库)
Celery -A forumend worker -l info -P eventlet
(注意这条命令是Windows端的命令)
显示:
3.浏览器打开路由器指定的视图,打开成功后,查看运行worker的终端,可见运行成功,结果为8
4.在redis查看结果
在redis数据库的0号数据库可以看到消息,2号数据库可以看到结果
有空再写写怎么实现周期任务......