celery(芹菜) 异步任务 定时任务 周期任务
什么是celery
Celery是一个简单、灵活且可靠的,处理大量消息的分布式系统
专注于实时处理的异步任务队列
同时也支持任务调度
celery架构
celery的架构由三部分组成,消息中间件(message broker),任务执行单元(worker)和任务执行结果存储(task result store)组成。
消息中间件
Celery本身不提供消息服务,但是可以方便的和第三方提供的消息中间件集成。包括,RabbitMQ, Redis等等
任务执行单元
Worker是Celery提供的任务执行的单元,worker并发的运行在分布式的系统节点中。
任务结果存储
Task result store用来存储Worker执行的任务的结果,Celery支持以不同方式存储任务的结果,包括AMQP, redis等
celery能做什么
异步任务
定时任务
周期任务
使用场景
耗时操作(所有的耗时操作都可以)将耗时操作任务提交给Celery去异步执行,比如发送短信/邮件、消息推送、音视频处理等等
定时任务(每天定时推送微信服务号消息,)定时执行某件事情,比如每天数据统计
使用
pip install celery
celery执行异步任务:
项目结构
celery的简单实例
celery_task_s1.py代码
from celery import Celery
#不加密码
broker = 'redis://127.0.0.1:6379/0' #指定broker
backend = 'redis://127.0.0.1:6379/1' #指定存储结果 # 加密码
# broker = 'redis://:123456@127.0.0.1:6379/2'
# backend = 'redis://:123456@127.0.0.1:6379/1' # 一定要指定一个名字
app = Celery('test',broker=broker,backend=backend) #任务其实就是个函数
# 需要用一个装饰器装饰,表示该任务是被celery管理的,并且可以用celery执行的
@app.task
def add(x,y) -> int:
import time
time.sleep(2)
return x+y
add_task.py
#用于提交任务的py文件 import celery_task_s1
#正常同步执行任务 会睡两秒在执行
# ret=celery_task_s1.add(3,4)
# print(ret) #提交任务到消息队列中
#只是把任务提交到消息队列中,并没有执行
# ret=celery_task_s1.add.delay(3,4)
# print(ret)
#a5ea035f-0cc3-44ba-b334-f5d7c7ce681d :任务的id号 #任务提交完成后,需要启动worker,可以用命令启动:
# celery worker -A celery_task_s1 -l info
#windows上:celery worker -A celery_task_s1 -l info -P eventlet win上首次使用worker需要安装eventlet模块
celery_result.py
from celery_task_s1 import app
from celery.result import AsyncResult async = AsyncResult(id='30314784-04bd-4ec5-acab-5cb22181cfcb',app=app) if async.successful():
#取出它return的值
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('任务已经开始被执行')
写一个py文件:celery_task
- 指定brokey(消息中间件),指定backend(结果存储)
- 实例化产生一个Celery对象,app=Celery('起一个名字',broker,backend)
- 加装饰器绑定任务,在函数(add)上加装饰器app.task
- 其他程序提交任务,先导入add, add.delay(参数,参数),会将该函数提交到消息中间件,但是并不会执行,有个返回值,直接print会打印出任务的id,以后用id去查询任务是否执行完成
- 启动worker去执行任务(worker可以先启动):
- celery worker -A celery_task_s1 -l info (-l是艾欧)
- Windows下:celery worker -A celery_task_s1 -l info -P eventlet (需要安装eventlet模块)
- 还有一种作为自执行文件启动,可以写在往里面放值的文件下面这样运行放值的模块的时候worker也启动了 但是win上好像不支持
from celery_app_task import cel
if __name__ == '__main__':
cel.worker_main()
# cel.worker_main(argv=['--loglevel=info')
- 查看结果:根据id去查询
async = AsyncResult(id="a5ea035f-0cc3-44ba-b334-f5d7c7ce681d", app=app)
if async.successful():
#取出它return的值
result = async.get()
print(result)
多任务结构
pro_cel
├── celery_task# celery相关文件夹
│ ├── celery.py # celery连接和配置相关文件,必须叫这个名字
│ └── order_task.py # 所有任务函数
│ └── user_task.py # 所有任务函数
├── celery_result.py # 检查结果
└── add_task.py # 触发任务
celery.py文件
#这个文件名必须叫celery,生成celery对象 from celery import Celery
from datetime import timedelta
from celery.schedules import crontab
broker = 'redis://127.0.0.1:6379/0'
backend = '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.timezone = 'Asia/Shanghai'
#是否使用UTC
# app.conf.enable_utc = False
order_task.py
from celery_task.celery import app
@app.task
def order_add(x,y):
import time
time.sleep(1)
return x+y
user_task.py
from celery_task.celery import app
@app.task
def user_add(x,y):
import time
time.sleep(1)
return x+y
add_task.py
from celery_task.order_task import order_add
from celery_task.user_task import user_add # ret=order_add.delay(5,6)
ret=user_add.delay(10,60)
print(ret)
celery_result.py
from celery.result import AsyncResult
from celery_task.celery import app
from add_task import ret async = AsyncResult(id='c951c4f7-dcfc-46fc-b60e-ee67b61211ec',app=app)
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: celery_task是包的名字(文件夹名字)
celery worker -A celery_task -l info -P eventlet #放值的时候手动启动add_task文件
celery执行定时任务
设定时间让celery执行一个任务
add_task.py 就是上面的执行异步任务的那个文件(往里面放值的时候使用定时方式)
#用于提交任务的py文件
import celery_task_s1
#执行定时任务:3s钟以后执行add任务
from datetime import datetime
# v1 = datetime(2019, 7, 12, 11, 13, 56)
# 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) #这里需要注意的是result是个对象,你可以直接打印因为内部写了__str__ #第二种获取时间的方法
ctime = datetime.now()
# 默认用utc时间
utc_ctime = datetime.utcfromtimestamp(ctime.timestamp())
from datetime import timedelta
#取10s之后的时间对象
time_delay = timedelta(seconds=3)
task_time = utc_ctime + time_delay
result = celery_task_s1.add.apply_async(args=[4, 3], eta=task_time)
print(result.id) #这里需要注意的是result是个对象,你可以直接打印因为内部写了__str__ #任务提交完成后,需要启动worker,可以用命令启动:
# celery worker -A celery_task_s1 -l info
#windows上:celery worker -A celery_task_s1 -l info -P eventlet
celery周期任务
多任务结构中celery.py修改如下
#这个文件名必须叫celery,生成celery对象 from celery import Celery
from datetime import timedelta
from celery.schedules import crontab
broker = 'redis://127.0.0.1:6379/0'
backend = '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.timezone = 'Asia/Shanghai'
#是否使用UTC
# app.conf.enable_utc = False #beat_schedule 定义定时任务的
app.conf.beat_schedule = {
#名字随意命令
'add-every-2-seconds':{
#执行tasks1下的test_celery函数
'task':'celery_task.order_task.order_add',
#每隔2秒执行一次
# 'schedule':1.0, 几秒钟几分钟几小时后schedule对应的参数
# 'schedule':crontab(minute='*/1'),
'schedule':timedelta(seconds=10),
#传递参数
'args':(5,6)
},
# 'add-every-12-seconds':{
# 'task':'celery_task.order_task.user_add',
# #每年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)
# }
}
创建worker的方式并没有发生变化,但是这里要注意的是,每间隔一定时间后需要生产出来任务给worker去执行,这里需要一个生产者beat
启动一个beat:(这个负责定时周期往里面放值)
celery beat -A celery_task -l info
启动worker执行(winds)
celery worker -A celery_task -l info -P eventlet
django中使用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
第一种 直接把多任务结构文件直接拷贝在项目目录下
注意在celery的任务函数中不能直接调用django的环境,需要手动添加
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "untitled15.settings")
import django
django.setup()
第二种 在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 #from 这个django项目 import celeryconfig就是上面配置的文件
BROKER_BACKEND='redis'
BOOKER_URL='redis://127.0.0.1:6379/1'
CELERY_RESULT_BACKEND='redis://127.0.0.1:6379/2'
https://www.cnblogs.com/znicy/p/5626040.html
http://www.manongjc.com/article/7864.html
celery(芹菜) 异步任务 定时任务 周期任务的更多相关文章
- Celery - 一个懂得 异步任务 , 定时任务 , 周期任务 的芹菜
1.什么是Celery?Celery 是芹菜Celery 是基于Python实现的模块, 用于执行异步定时周期任务的其结构的组成是由 1.用户任务 app 2.管道 broker 用于存储 ...
- Celery 异步任务 , 定时任务 , 周期任务 的芹菜
1.什么是Celery?Celery 是芹菜Celery 是基于Python实现的模块, 用于执行异步定时周期任务的其结构的组成是由 1.用户任务 app 2.管道 broker 用于存储 ...
- Celery - 异步任务 , 定时任务 , 周期任务
1.什么是Celery?Celery 是芹菜Celery 是基于Python实现的模块, 用于执行异步定时周期任务的其结构的组成是由 1.用户任务 app 2.管道 broker 用于存储 ...
- django —— Celery实现异步和定时任务
1. 环境 python==2.7 djang==1.11.2 # 1.8, 1.9, 1.10应该都没问题 celery-with-redis==3.0 # 需要用到redis作为中间人服务(Bro ...
- Celery+python+redis异步执行定时任务
我之前的一篇文章中写了[Celery+django+redis异步执行任务] 博文:http://blog.csdn.net/apple9005/article/details/54236212 你会 ...
- Django搭配Celery进行异步/定时任务(一)初步搭建
以下需求场景很常见: 1. 用户点击页面按钮,请求后台进行一系列耗时非常高的操作,页面没有响应/一直Loading,用户体验非常不好. 2. 某些数据需要预先处理,每天凌晨的时候进行运算,大约半小时到 ...
- celery执行异步任务和定时任务
一.什么是Clelery Celery是一个简单.灵活且可靠的,处理大量消息的分布式系统 专注于实时处理的异步任务队列 同时也支持任务调度 Celery架构 Celery的架构由三部分组成,消息中间件 ...
- celery介绍、架构、快速使用、包结构,celery执行异步、延迟、定时任务,django中使用celery,定时更新首页轮播图效果实现,数据加入redis缓存的坑及解决
今日内容概要 celery介绍,架构 celery 快速使用 celery包结构 celery执行异步任务 celery执行延迟任务 celery执行定时任务 django中使用celery 定时更新 ...
- 日夕如是寒暑不间,基于Python3+Tornado6+APScheduler/Celery打造并发异步动态定时任务轮询服务
原文转载自「刘悦的技术博客」https://v3u.cn/a_id_220 定时任务的典型落地场景在各行业中都很普遍,比如支付系统中,支付过程中因为网络或者其他因素导致出现掉单.卡单的情况,账单变成了 ...
随机推荐
- 2019.6.28 校内测试 T4 【音乐会】达拉崩吧·上
考试的一道附加题~ 一看题目描述:把区间[l,r]里每个数异或上x,求区间[l,r]里所有数的异或和,这明显的要用数据结构或RMQ吧. 恩,所以正解就是线段树啦,至于树状数组行与否,不知道~ wate ...
- Ubuntu 14.04 64bit中永久添加DNS的方法
第一种方法修改如下文件,默认是空的sudo vim /etc/resolvconf/resolv.conf.d/base在里面加入你想添加的DNS服务器,一行一个nameserver 114.114. ...
- c++ 容器切片反转次序(不拷贝到新容器)
// rotate algorithm example #include <iostream> // cout #include <algorithm> // rotate # ...
- Spring事务异常回滚
最近遇到了事务不回滚的情况,我还考虑说JPA的事务有bug? 我想多了....... 为了打印清楚日志,很多方法我都加tyr catch,在catch中打印日志.但是这边情况来了,当这个方法异常 ...
- WIN10环境下点击通知栏图标时自动切换输入法导致图标位置变动
这个问题由来已久,每当点击系统右下角任务栏中的按钮时,原本是搜狗输入法就会自动变成“US [ 中文(简体,中国) ]”,图标会自动错位,导致响应的是其他功能. 假设上图是正常的环境,此时我点击电池图标 ...
- 安装windows下安装mysql
参考文档:https://www.cnblogs.com/reyinever/p/8551977.html https://www.jb51.net/article/151213.htm 首先下载m ...
- python 库 imgaug数据增强
安装及详细使用方法介绍: https://blog.csdn.net/qq_38451119/article/details/82428612 pip install imgaug 失败解决方法: 提 ...
- BitmapDrawable
对Bitmap的一种封装,可以设置它包装的bitmap在BitmapDrawable区域中的绘制方式,有: 平铺填充,拉伸填或保持图片原始大小!以<bitmap>为根节点! 可选属性如下: ...
- List的remove方法里的坑
今天遇到一件怪事,用一个ArrayList添加了一个对象,再调用ArrayList的remove方法删除该对象,当然这时对象是数据库里查出来的,但内容绝对是一样,却发现remove失败了.演示一下,这 ...
- pyCharm最新2017激活
pyCharm最新2017:下载地址 下载完成后安装软件 启动pyCharm,进入下面窗口 选择License server 在 server选项里边输入 http://elporfirio.com: ...