Celery 收下这捆芹菜!
Celery简介
Celery是一个强大的 分布式任务队列 的 异步处理框架,它可以让任务的执行完全脱离主程序,甚至可以被分配到其他主机上运行。我们通常使用它来实现异步任务(async task)和定时任务(crontab)
Celery 官网:http://www.celeryproject.org/
Celery 官方文档英文版:http://docs.celeryproject.org/en/latest/index.html
Celery 官方文档中文版:http://docs.jinkan.org/docs/celery/
Celery构成
Task
任务模块, 包含异步任务和定时任务, 异步任务通常在业务逻辑中被触发并发往Broker任务队列, 定时任务由Celery Beat 进程周期性地发往Broker任务队列
Broker
消息中间件, 就是任务调度队列, 用来接收任务, 将任务存储到队列中, 就像是生产者与消费者模型中的队列一样
Celery本身不提供Broker, 官方推荐使用RabbitMQ和Redis
Worker
任务的执行单元, 它实时监控Broker队列, 获取队列中的任务, 并执行, 可以看做是生产者与消费者模型中的消费者
Backend
任务执行结果的存储单元, 用来存储任务结果, 以便查询
Celery本身不提供Backend, 官方推荐使用RabbitMQ和Redis

Celery使用
安装
python安装Celery: pip install celery
我们使用Redis作为Broker和Backend, 因此确保你的设备配置了Redis环境
基本使用
"""
project
├── celery_task # celery包
│ ├── __init__.py # 包文件
│ ├── celery.py # celery连接和配置相关文件,且名字必须是celery.py
│ └── tasks.py # 所有任务函数
├── add_task.py # 添加任务
└── get_result.py # 获取结果
"""
异步任务: delay
"""
1.执行add_task.py将任务添加到队列
2.cmd切换至所在文件目录celery_task下运行worker:
>: celery worker -A celery_task -l info -P eventlet
3.执行get_result.py获取任务结果
"""
# celery.py
from celery import Celery
# 配置消息中间件, 用来接收任务
broker = 'redis://127.0.0.1:6379/0'
# 配置backend, 用来存储任务执行结果
backend = 'redis://127.0.0.1:6379/1'
# worker, 任务执行单元
app = Celery(broker=broker, backend=backend)
# tasks.py
from .celery import app
# 定义任务
@app.task
def add(x, y):
res = x + y
print(f'{x}+{y}={res}')
return res
@app.task
def minus(x, y):
res = x - y
print(f'{x}-{y}={res}')
return res
# add_task.py
from .tasks import add, minus
# 在业务逻辑中触发异步任务
add_results = add.delay(10, 20)
# 任务执行结果的id
print(add_results.id)
# get_result.py
from .celery import app
from .add_tasks import add_results
from celery.result import AsyncResult
if __name__ == '__main__':
# 获取异步任务结果对象, 参数:id, app
async = AsyncResult(id=add_results.id, app=app)
if async.successful():
result = async.get()
print('任务执行成功')
print(result)
elif async.failed():
print('任务失败')
elif async.status == 'PENDING':
print('任务等待中被执行')
elif async.status == 'RETRY':
print('任务异常后正在重试')
elif async.status == 'STARTED':
print('任务已经开始被执行')
延迟任务: apply_async
from celery_task.tasks import add
from datetime import timedelta, datetime
# 添加延时任务, 10秒后执行
add_results = add.apply_async(args=(10, 20), eta=datetime.utcnow() + timedelta(seconds=10))
# 任务执行结果的id
print(add_results.id)
周期任务: beat_schedule
注意: 周期任务是通过 celery beat 来周期性添加的, , 因此启动worker服务之后, 还要重开一个cmd窗口启动beat服务: celery beat -A celery_task -l info
# celery.py
from celery import Celery
from datetime import timedelta
from celery.schedules import crontab
# 配置消息中间件, 用来接收任务
broker = 'redis://127.0.0.1:6379/0'
# 配置backend, 用来存储任务执行结果
backend = 'redis://127.0.0.1:6379/1'
# worker, 任务执行单元
app = Celery(broker=broker, backend=backend, include=['celery_task.tasks'])
# 时区
app.conf.timezone = 'Asia/Shanghai'
app.conf.enable_utc = False
app.conf.beat_schedule = {
'add-task': {
'task': 'celery_task.tasks.add',
# 每10秒添加一次任务
'schedule': timedelta(seconds=10),
'args': (10, 20)
},
'minus-task': {
'task': 'celery_task.tasks.minus',
# 每周一八点半添加一次任务
'schedule': crontab(hour=8, minute=30, day_of_week=1),
'args': (20, 10)
}
}
Django配置Celery
在根目录下创建包文件夹 celery_task
"""
project
├── celery_task # celery包
├── __init__.py # 包文件
├── celery.py # celery连接和配置相关文件,且名字必须是celery.py
└── tasks.py # 所有任务函数
"""
celery.py
# 1.加载Django配置环境
import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE", 'luffyapi.settings.dev')
# 2.加载Celery配置环境
from celery import Celery
broker = 'redis://127.0.0.1:6379/0'
backend = 'redis://127.0.0.1:6379/1'
app = Celery(broker=broker, backend=backend, include=['celery_task.tasks.py'])
# 时区
app.conf.timezone = 'Asia/Shanghai'
# UTC
app.conf.enable_utc = False
from datetime import timedelta
app.conf.beat_schedules = {
'update-banner-cache': {
'task': 'celery_task.tasks.py.update_banner_cache',
# 每10秒添加一次
'schedule': timedelta(seconds=10),
'args': ()
}
}
task.py
from .celery import app
from home.models import Banner
from home.serializers import BannerModerSerializer
from django.conf import settings
from django.core.cache import cache
@app.task
def update_banner_cache():
print('lalal')
banner_query = Banner.objects.filter(is_delete=False, is_show=True).order_by('-order').all()
serializer_obj = BannerModerSerializer(data=banner_query, many=True)
banner_data = serializer_obj.data
for banner in banner_data:
banner['image'] = settings.BASE_URL + banner.get('image')
cache.set('banner_cache', banner_data)
return True
Celery 收下这捆芹菜!的更多相关文章
- 毕业季offer怎么拿?收下这份非典型求职面试指南
摘要:求职面试莫慌,先自我评估一下 ,华为云专家手把手为你指导. 本文分享自华为云社区<毕业季offer怎么拿?收下这份非典型求职面试指南>,原文作者:技术火炬手 . 又是一年毕业季,对于 ...
- Java开发者必备的10大学习网站,送给入门学习java的你,请收下!
作为开发者来说,必备的除了对编码的热情还要有自己的一套技巧,另外不可缺少的就是平时学习的网站.以下本人收集的 Java 开发者必备的网站,这些网站可以提供信息.以及一些很棒的讲座 , 还能解答一般问题 ...
- java枚举使用详解,整理的很好,只能收下。。。
java枚举使用详解 在实际编程中,往往存在着这样的“数据集”,它们的数值在程序中是稳定的,而且“数据集”中的元素是有限的. 例如星期一到星期日七个数据元素组成了一周的“数据集”,春夏秋冬四个数据元素 ...
- 301重定向方法大全及SEO中网址规范化,看着不错先收下
301重定向方法大全及SEO中网址规范化 现在大多数网站都存在一些内容相同但网址(URL)不一样的重复内容,这些重复的内容对于搜索引擎来说却可能被认为是复制网页,复制网页虽然不会被惩罚但因多个网址存在 ...
- 这份Koa的简易Router手敲指南请收下
上一期链接--也就是本文的基础,参考KOA,5步手写一款粗糙的web框架 本文参考仓库:点我 Router其实就是路径匹配,通过匹配路径,返回给用户相应的网站内容. 以下方例子为例,主要通过提取req ...
- JAVA工程师必学技能,进阶&涨薪的推进器!这份实战教程请收下
Netty 作为互联网中间件的基石,是 JAVA 工程师进阶为高级程序员必备的能力之一.也是目前是互联网中间件领域使用最广泛最核心的网络通信框架. Netty是一个高性能.异步事件驱动的NIO框架,它 ...
- Python的22个编程技巧,请收下!
1. 原地交换两个数字 Python 提供了一个直观的在一行代码中赋值与交换(变量值)的方法,请参见下面的示例: x,y= 10,20 print(x,y) x,y= y,x print(x,y) # ...
- 前端面试?这份手撸Promise请你收下
前言 现在很多大厂面试前端都会要求能够手动的写出一个Promise,所以这里整理了一份手写的Promise. 绝对详细,功能绝对强大.如果你不了解Promise的基本使用,那么本篇文章可能不太适合你, ...
- 收下这款 Vue 项目模版,它将让你的开发效率在 2021 年提高 50%
这是什么 vue-automation 是一款开箱即用的 Vue 项目模版,它基于 Vue CLI 4 众所周知,虽然 Vue CLI 提供了脚手架的功能,但由于官方的脚手架过于简单,运用在实际项目开 ...
随机推荐
- oracle使用TKPROF 工具来查询SQL性能状态
SQL trace 工具收集正在执行的SQL的性能状态数据并记录到一个跟踪文件中. 这个跟踪文件提供了许多有用的信息,例如解析次数.执行次数,CPU使用时间等.这些数据将可以用来优化你的系统. 设置S ...
- kwargs.pop是什么意思
pop()函数一般用来删除list列表的末尾元素,同样,kwargs.pop()用来删除关键字参数中的末尾元素,比如:kwargs = {'Michael': 95, 'Bob': 75, 'Trac ...
- spring mvc 接收表单 bean
spring MVC如何接收表单bean 呢? 之前项目中MVC框架一直用struts2,所以我也就按照struts2 的思维来思考 页面loginInput.jsp: <?xml versio ...
- 最小生成树kruskal算法、
克鲁斯卡尔(kruskal) //kruskal算法生成最小生成树. //对边集数组Edge结构的定义 typedef struct { int begin; int end; int weight; ...
- pytorch lstm crf 代码理解 重点
好久没有写博客了,这一次就将最近看的pytorch 教程中的lstm+crf的一些心得与困惑记录下来. 原文 PyTorch Tutorials 参考了很多其他大神的博客,https://blog.c ...
- ios9.3.3 h5的js代码全部失效
做微信公众号页面时,ios9.3.3 h5的js代码全部失效描述: 机型iphone6 plus,ios9.3.3js代码全部失效,刚开始还以为是ios和jq兼容问题, 后来发现是es6语法不能读,导 ...
- Python 3里,reduce()函数已经被从全局名字空间里移除了,它现在被放置在fucntools模块里
reduce函数:在Python 3里,reduce()函数已经被从全局名字空间里移除了,它现在被放置在fucntools模块里 用的话要 先引入:>>> from functool ...
- P1080 探测器
题目描述 一个 n*n 的网格图上有 m 个探测器,每个探测器有个探测半径r,问这 n*n 个点中有多少个点能被探测到. 网格图上的点的坐标从(1,1)到(n,n). 输入格式 第一行3个整数n,m, ...
- P1003 电影票价
题目描述 已知一位小朋友的电影票价是10元,请问 \(n\) 位小朋友的总票价是多少? 输入格式 输入一个整数 \(n(1 \le n \le 1000)\) , 用于表示小朋友的数量. 输出格式 输 ...
- antd Bug记录
antd-mobile Carousel 走马灯竖向滚动内容为空会导致visibility:hidden; Carousel Banner轮播组件初始化加载高度不正确可以在第一张图片onload事件的 ...