celery(本质是对消息队列的封装)
不支持在windows平台使用

异步任务框架:执行异步任务,执行延迟任务,执行定时任务,

Celery的架构由三部分组成:

  1. 任务中间件(message broker),存储任务的,

  2. 任务执行单元worker,执行任务的

  3. 任务结果存储(task result store)组成,存储任务结果的

1)可以不依赖任何服务器,通过自身命令,启动服务(内部支持socket)
2)celery服务为为其他项目服务提供异步解决任务的需求
注:会有两个服务同时运行,一个是项目服务,一个是celery服务,项目服务将需要异步处理的任务交给celery服务,celery就会在需要时异步完成项目的需求

img

pip install celery

# 新建一个文件夹,本例中名为:celery_task,在文件夹中必须有一个celery.py文件,在这个文件中写一些配置
from celery import Celery


broker='redis://:123456@127.0.0.1:6379/1'  # 123456是redis密码,存储任务的redis库
backend='redis://127.0.0.1:6379/2'  # 没有带密码的写法,存储任务结果的redis库
# 把要执行的任务所在的文件注册进来,不同的任务最好放到不同的文件
app=Celery(__name__,broker=broker,backend=backend,include=['celery_task.home_task',])


# 启动worker
# 命令行先切换到了celery_task文件夹所在的目录D:\Program Files\luffyapi>
# 然后执行以下命令
# -l info l表示日志,info表示日志级别,-A表示在app所在的文件夹,默认从当前目录下寻找这个文件夹
celery -A celery_task worker -l info  -P eventlet (在Windows上要加-P eventlet,要先安装pip install eventlet)


celery --app=proj worker -l INFO #proj是celery.py所在的文件夹名
celery --app=celery_task worker -l INFO
celery -A proj worker --concurrency=1000 -P eventlet 

在django中执行:添加任务到redis的操作,然后celery的worker从redis中拿出任务来执行,把结果放到redis中,

执行延迟任务

from celery_task.task1 import add	# add是task1.py中一个做加法的函数
from datetime import datetime,timedelta

# 要使用utc时间,通过utcnow获得utc时间,3秒后执行
eta=datetime.utcnow()+timedelta(seconds=3)	# days=1
res=add.apply_async(args=(3,4),eta=eta)	#3秒后执行这个任务
# res是结果的id号,通过这个id号可以拿到结果

执行定时任务

celery框架django项目工作流程

1)加载django配置环境
2)配置broker和backend,创建Celery框架对象app,得到的app就是worker
3)给worker对应的app添加可处理的任务函数,用include配置给worker的app
4)完成提供的任务的定时配置app.conf.beat_schedule
5)启动celery服务,运行worker,执行任务
6)启动beat服务,运行beat,添加任务

重点:由于采用了django的反射机制,使用celery.py所在的celery_task包必须放置在项目的根目录下

# 这条命令的作用是:定时把任务提交到broker里面
celery -A celery_task beat -l info


from celery import Celery
import os
import django
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "luffyapi.settings.dev")
django.setup()

broker='redis://127.0.0.1:6379/1'  # 没有带密码
backend='redis://127.0.0.1:6379/2'  # 没有带密码
# 把要执行的任务所在的文件注册进来
app=Celery(__name__,broker=broker,backend=backend,include=['celery_task.home_task',])

# 时区
app.conf.timezone = 'Asia/Shanghai'
# 是否使用UTC
app.conf.enable_utc = False

# 任务的定时配置
from datetime import timedelta
from celery.schedules import crontab
app.conf.beat_schedule = {
    'add-task': {
        'task': 'celery_task.task1.add',	# add是task1.py中一个做加法的函数
        'schedule': timedelta(seconds=5),
        # 'schedule': crontab(hour=8, day_of_week=1),  # 每周一早八点
        'args': (300, 150),		# args是task任务的参数
    }
}

在task.py中的一个任务,

from .celery import app


@app.task  # 都要添加装饰器
def mutiple(x,y):
    print(x,y)
    return x*y