celery使用
celery使用
celery基本使用
1.创建python项目 celerytest
2.创建celery_app_task.py
import celery
#任务结果存储
backend = "redis://127.0.0.1:6379/1"
#消息队列
broker="redis://127.0.0.1:6379/2"
#生成cel对象,异步执行任务,第一个参数任务名
cel = celery.Celery("test",backend=backend,broker=broker)
#绑定任务,需要异步执行的任务
@cel.task
def add(x,y):
return x+y
3.创建add_task.py 提交任务
from celery_app_task import add
#提交异步任务 delay
result = add.delay(4,5)
#提交任务的结果为唯一标识码,用于查询任务结果
print(result)
4.生成worker用于执行任务
#切到项目根目录下,celery_app_task为创建的celery配置所在py文件名
celery worker -A celery_app_task -l info -P eventlet
#linux系统命令:celery worker -A celery_app_task -l info
#window系统命令:celery worker -A celery_app_task -l info -P eventlet
5.创建result.py查看任务执行结果
from celery.result import AsyncResult
from celery_app_task import cel
#id就是提交任务后生成的唯一标识码
async = AsyncResult(id="e919d97d-2938-4d0f-9265-fd8237dc2aa3", app=cel)
#返回不同的查询结果
if async.successful():
result = async.get()
print(result)
# result.forget() # 将结果删除
elif async.failed():
print('执行失败')
elif async.status == 'PENDING':
print('任务等待中被执行')
elif async.status == 'RETRY':
print('任务异常后正在重试')
elif async.status == 'STARTED':
print('任务已经开始被执行')
多任务结构
pro_cel
├── celery_task# celery相关文件夹
│ ├── celery.py # celery连接和配置相关文件,必须叫这个名字
│ └── tasks1.py # 所有任务函数
│ └── tasks2.py # 所有任务函数
├── check_result.py # 检查结果
└── send_task.py # 触发任务
多任务结构使用
1.创建celery_task文件夹
2.在celery_task文件夹下创建celery.py文件,必须叫celery,配置消息队列和储存队列
from celery import Celery
cel = Celery('celery_demo',
broker='redis://127.0.0.1:6379/1',
backend='redis://127.0.0.1:6379/2',
# 包含以下两个任务文件,去相应的py文件中找任务,对多个任务做分类
include=['celery_task.task1',
'celery_task.task2'
])
# 时区
cel.conf.timezone = 'Asia/Shanghai'
# 是否使用UTC
cel.conf.enable_utc = False
3.
#task1.py
import time
from celery_task.celery import cel
@cel.task
def add(x,y):
time.sleep(10)
return x+y
#task2.py
import time
from celery_task.celery import cel
@cel.task
def substract(x,y):
time.sleep(10)
return x-y
#add_task.py
from celery_task.tasks1 import add
from celery_task.tasks2 import substract
# 立即告知celery去执行test_celery任务,并传入一个参数
res1 = add.delay('第一个的执行')
res2 = substract.delay('第二个的执行')
print(res1)
print(res2)
#result.py
from celery.result import AsyncResult
from celery_task.celery import cel
async = AsyncResult(id="08eb2778-24e1-44e4-a54b-56990b3519ef", app=cel)
if async.successful():
result = async.get()
print(result)
# result.forget() # 将结果删除,执行完成,结果不会自动删除
# async.revoke(terminate=True) # 无论现在是什么时候,都要终止
# async.revoke(terminate=False) # 如果任务还没有开始执行呢,那么就可以终止。
elif async.failed():
print('执行失败')
elif async.status == 'PENDING':
print('任务等待中被执行')
elif async.status == 'RETRY':
print('任务异常后正在重试')
elif async.status == 'STARTED':
print('任务已经开始被执行')
#注意:多任务生成worker时,task为文件夹名,放置celery.py的文件夹
celery worker -A task -l info -P eventlet
celery执行定时任务
定时任务分三种:
1.具体时间执行一次任务,例如2019/4/18/14:00去掏粪
2.当前时间延迟一段时间后执行一次任务,例如定时炸弹,开启后30s爆炸
3.每到一个指定时间就执行一次任务,例如女朋友生日,到了就要送礼物
celery提交定时任务需要特定的角色来提交
celery beat -A task -l info
#1.执行一个具体时间的任务,只执行一次,例如 2019/4/18/14:00去掏粪
from celery_task import draw_out_pung
from datetime import datetime
v1 = datetime(2019, 2, 13, 18, 19, 56)#当前时间
print(v1)
'''
设置了以下参数就不用转换了
时区
cel.conf.timezone = 'Asia/Shanghai'
是否使用UTC
cel.conf.enable_utc = False
'''
v2 = datetime.utcfromtimestamp(v1.timestamp())#utc时间
print(v2)
#定时任务 apply_async
result = draw_out_pung.apply_async(eta=v2)
print(result)
#2.一段时间间隔后执行任务
ctime = datetime.now()
# 默认用utc时间
utc_ctime = datetime.utcfromtimestamp(ctime.timestamp())
from datetime import timedelta
time_delay = timedelta(seconds=10)
task_time = utc_ctime + time_delay
# 使用apply_async并设定时间
result = add.apply_async(args=[4, 3], eta=task_time)
print(result.id)
#3.到特定时间就执行
#在配置文件中增加cel.conf.beat_schedule,设置好时间和要执行的任务,开启
#beat和worker后自动提交任务和执行任务
from datetime import timedelta
from celery import Celery
from celery.schedules import crontab
cel = Celery('tasks', broker='redis://127.0.0.1:6379/1', backend='redis://127.0.0.1:6379/2', include=[
'celery_task.tasks1',
'celery_task.tasks2',
])
cel.conf.timezone = 'Asia/Shanghai'
cel.conf.enable_utc = False
cel.conf.beat_schedule = {
# 名字随意命名
'add-every-10-seconds': {
# 执行tasks1下的test_celery函数
'task': 'celery_task.tasks1.test_celery',
# 每隔2秒执行一次
# 'schedule': 1.0,
# 'schedule': crontab(minute="*/1"),
'schedule': timedelta(seconds=2),
# 传递参数
'args': ('test',)
},
# 'add-every-12-seconds': {
# 'task': 'celery_task.tasks1.test_celery',
# 每年4月11号,8点42分执行
# 'schedule': crontab(minute=42, hour=8, day_of_month=11, month_of_year=4),
# 'schedule': crontab(minute=42, hour=8, day_of_month=11, month_of_year=4),
# 'args': (16, 16)
# },
}
django中使用celery
在celery中用到django的表,需要使用在脚本中使用django表模型的语句
import os
os.environ.setdefault('DJANGO_SETTINGS_MODULE','dj35_1.settings')
#直接导入django,并运行
import django
django.setup()
#导入models模块需要使用的类
from app0.models import User
django版本要与django-celery版本匹配,不然报错
推荐使用多任务结构使用celery
安装包
celery==3.1.25
django-celery==3.1.20
在项目目录下创建celeryconfig.py
import djcelery
djcelery.setup_loader()
CELERY_IMPORTS=(
'app01.tasks',
)
#有些情况可以防止死锁
CELERYD_FORCE_EXECV=True
# 设置并发worker数量
CELERYD_CONCURRENCY=4
#允许重试
CELERY_ACKS_LATE=True
# 每个worker最多执行100个任务被销毁,可以防止内存泄漏
CELERYD_MAX_TASKS_PER_CHILD=100
# 超时时间
CELERYD_TASK_TIME_LIMIT=12*30
在app01目录下创建tasks.py
from celery import task
@task
def add(a,b):
with open('a.text', 'a', encoding='utf-8') as f:
f.write('a')
print(a+b)
视图函数views.py
from django.shortcuts import render,HttpResponse
from app01.tasks import add
from datetime import datetime
def test(request):
# result=add.delay(2,3)
ctime = datetime.now()
# 默认用utc时间
utc_ctime = datetime.utcfromtimestamp(ctime.timestamp())
from datetime import timedelta
time_delay = timedelta(seconds=5)
task_time = utc_ctime + time_delay
result = add.apply_async(args=[4, 3], eta=task_time)
print(result.id)
return HttpResponse('ok')
settings.py
INSTALLED_APPS = [
...
'djcelery',
'app01'
]
...
from djagocele import celeryconfig
BROKER_BACKEND='redis'
BOOKER_URL='redis://127.0.0.1:6379/1'
CELERY_RESULT_BACKEND='redis://127.0.0.1:6379/2'