celery-2

1、celery执行定时任务

1)几点几分执行:

celery_task-s1.py

from celery import Celery
import time

# redis不加密码
broker='redis://127.0.0.1:6379/0'
backend='redis://127.0.0.1:6379/1'

app=Celery('test',backend=backend,broker=broker)

@app.task  # @app名字.task
def add(x,y):
    time.sleep(2)
    return x+y


add_task.py

# 2020/2/21 22:38:30开始执行任务
from datetime import datetime
v1 = datetime(2020, 3, 21, 22, 38, 30)
print(v1)

v2 = datetime.utcfromtimestamp(v1.timestamp())
print(v2)

# 取出要执行任务的时间对象,调用apply_async方法,args是任务函数的参数,eta是执行的时间
result = celery_task_s1.add.apply_async(args=[1, 3], eta=v2)
print(result.id)


此时启动work和broker,程序会等到指定的那个时间才会执行;


2)多长时间后执行

add_task.py

from datetime import datetime

ctime = datetime.now()

# 默认用utc时间
utc_ctime = datetime.utcfromtimestamp(ctime.timestamp())
from datetime import timedelta

#取10秒之后的时间对象
time_delay = timedelta(seconds=10)
task_time = utc_ctime + time_delay

# 使用apply_async并设定时间
result = celery_task_s1.add.apply_async(args=[4, 3], eta=task_time)
print(result.id)


此时启动work和broker,程序会等到10秒后才会执行;


2、执行计划任务

类似于contab的定时任务


案例, (用的是多任务机构):

celery.py

from celery import Celery
from datetime import timedelta
from celery.schedules import crontab

backend='redis://127.0.0.1:6379/0'
broker='redis://127.0.0.1:6379/1'

app=Celery('test',broker=broker, backend=backend,
           # 包含以下两个任务文件,去相应的py文件中找任务,对多个任务做分类
           include=['celery_task.order_task',
                    'celery_task.user_task'
           ])


# 字典里可以写多个不同的任务
app.conf.beat_schedule = {
    # 名字随意命名
    'add-every-10-seconds': {
        # 执行order_task下的test_celery函数
        'task': 'celery_task.order_task.order_add',
        # 每隔10秒执行一次
        # 'schedule': 1.0,
        # 'schedule': crontab(minute="*/1"),
        'schedule': timedelta(seconds=10),
        # 给任务函数传递参数
        'args': (5, 6)
    },
    # 'add-every-12-seconds': {
    #     'task': 'celery_task.order_task.order_add',
    #     # 每年3月21号,23点15分执行
    #     'schedule': crontab(minute=15, hour=23, day_of_month=21, month_of_year=3),
    #     'args': (16, 16)
    # },

}


order_task.py

import time
from celery_task.celery import app

@app.task
def order_add(x, y):
    time.sleep(1)
    return x + y


此时需要先启动一个beat:celery beat -A celery_task -l info

前面都是手动提交任务,这个beat会自动帮我们提交任务,而且周期是我们任务里指定的,我这里是10秒,它就会10秒提交一次;

然后启动work,celery worker -A celery_task -l info -P eventlet    

work就会每隔10秒接收一次任务,并一直循环执行;


3、django中使用celery

直接把多任务结构copy过来,使用即可;

image

celery_task是在项目目录下;


celery.py

from celery import Celery

backend='redis://127.0.0.1:6379/0'
broker='redis://127.0.0.1:6379/1'

app=Celery('test',broker=broker, backend=backend,
           # 包含以下两个任务文件,去相应的py文件中找任务,对多个任务做分类
           include=['celery_task.order_task',
                    'celery_task.user_task'
           ])


user_task.py

import time
from celery_task.celery import app

@app.task
def user_add(x, y):
    time.sleep(1)
    return x + y


views.py

from django.shortcuts import render, HttpResponse
from celery_task.user_task import user_add
from celery.result import AsyncResult
from celery_task.celery import app

# Create your views here.
def index(request):
    result = user_add.delay(8, 9)
    return HttpResponse(result.id)


def check_result(request):
    res = request.GET.get('id')
    async = AsyncResult(id=res, app=app)
    if async.successful():
        # 取出return值
        result = async.get()
        print(result)
        return HttpResponse('任务执行完成')


urls.py

from django.conf.urls import url
from django.contrib import admin
from app01 import views

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^index/', views.index),
    url(r'^check/', views.check_result),
]


需要先启动work: celery worker -A celery_task -l info -P eventlet

然后启动django,在浏览器中访问:

image 

image

先访问了index,index视图函数中执行了任务;

然后拿到任务id,再访问check手动查询结果;


注意:
在celery的任务函数中不能直接调用django的环境,比如要使用ORM就不行,需要手动添加django环境才行;

import os

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "BMS.settings")
    import django     # 加载django
    django.setup()   # 启动django

    from app01 import models  # 这样就能使用ORM了
    ......


4、django-celery

其实除了原生的celery模块,django也提供了一个django-celery模块,但据说不太好用;

如果使用到了再看吧;

猜你喜欢

转载自www.cnblogs.com/weiyiming007/p/12543554.html