Celery异步分布队列
Celery分布式任务队列
一、Celery介绍celery periodic task
Celery 是一个基于python开发的分布式异步消息任务队列,通过它可以轻松的实现任务的异步处理,如果你的业务场景中需要用到异步任务,就可以考虑使用celery,例:
1.你想对100台机器执行一条批量命令,可能会花很长时间,但不想让程序等着结果返回,而是给你返回一个任务ID,你过一段时间只需要拿着这个任务id就可以拿到任务执行结果,在任务执行ing进行时,你可以继续做其它的事情。
2.你想做一个定时任务,比如每天检测一下你们所有客户的资料,如果发现今天是客户的生日,就给他发个短信祝福
Celery在执行任务时需要通过一个消息中间件和发送任务消息,以及存储任务结果,一般使用rabbitMQ or Redis
Celery有以下优点:
- 简单:一旦熟悉了celery的工作流程后,配置和使用还是比较简单的
- 高可用:当任务执行失败或执行过程中发生链接中断,celery会自动尝试重新执行任务
- 快速:一个单进程的Celery每分钟可处理上百万个任务
- 灵活:几乎celery的各个组件都可以被扩展及自定制
任务队列是一种跨线程、跨机器工作的一种机制.
任务队列中包含称作任务的工作单元。有专门的工作进程持续不断的监视任务队列,并从中获得新的任务并处理.
celery通过消息(任务)进行通信,通常使用一个叫Broker(中间人)来协助clients(任务的发出者)和worker(任务的处理者). clients发出消息到队列中,broker将队列中的信息派发给worker来处理。
Celery的架构
Celery的架构由三部分组成,消息队列(message broker),任务执行单元(worker)和任务执行结果存储(task result store)组成。
一个celery系统可以包含很多的worker和broker
Celery本身不提供消息队列功能,但是可以很方便地和第三方提供的消息中间件进行集成,包括RabbitMQ,Redis,MongoDB等
二、安装
pip install -U celery==4.4.7 -i https://pypi.tuna.tsinghua.edu.cn/simple
注意:
Celery不建议在windows系统下使用,因为Celery在4.0版本以后,不再支持windows系统,所以如果要在windows下使用只能安装4.0以前的版本,而且即便是4.0之前的版本,在windows系统下也是不能单独使用的,需要安装eventlet模块
也可从官方直接下载安装包:https://pypi.python.org/pypi/celery/
tar xvfz celery-4.4.7.tar.gz
cd celery-4.4.7
python setup.py build
python setup.py install
三、使用
使用celery第一件要做的最为重要的事情是需要先创建一个Celery实例,我们一般叫做celery应用,或者更简单直接叫做一个app。app应用是我们使用celery所有功能的入口,比如创建任务,管理任务等,在使用celery的时候,app必须能够被其他的模块导入。
一般celery任务目录直接放在项目的根目录下即可,路径:
luffyapi/
├── mycelery/
├── config.py # 配置文件
├── __init__.py
├── main.py # 主程序
└── sms/ # 一个目录可以放置多个任务,该目录下存放当前任务执行时需要的模块或依赖
└── tasks.py # 任务的文件,名称必须是这个!!!
main.py,代码:
# 主程序
from celery import Celery
# 创建celery实例对象
app = Celery("luffy")
# 通过app对象加载配置
app.config_from_object("mycelery.config")
# 自动搜索并加载任务
# 参数必须必须是一个列表,里面的每一个任务都是任务的路径名称
# app.autodiscover_tasks(["任务1","任务2",....])
app.autodiscover_tasks(["mycelery.sms","mycelery.email"])
# 启动Celery的命令
# 强烈建议切换目录到项目的根目录下启动celery!!
# celery -A mycelery.main worker --loglevel=info
配置文件config.py,代码:
# 任务队列的链接地址
broker_url = 'redis://127.0.0.1:6379/15'
# 结果队列的链接地址
result_backend = 'redis://127.0.0.1:6379/14'
创建一个任务文件sms/tasks.py,并创建任务,代码:
# celery的任务必须写在tasks.py的文件中,别的文件名称不识别!!!
from mycelery.main import app
@app.task # name表示设置任务的名称,如果不填写,则默认使用函数名做为任务名
def send_sms():
print("发送短信!!!")
@app.task(name="send_sms2") # name表示设置任务的名称,如果不填写,则默认使用函数名做为任务名
def send_sms2():
print("发送短信任务2!!!")
在程序中调用上面的异步任务,拿django进行举例:
# 调用celery执行异步任务
from my_celery.sms.tasks import send_sms
send_sms.delay(mobile)
其他参考文档:
http://docs.celeryproject.org/en/latest/getting-started/introduction.html
https://github.com/celery/celery/tree/master/examples/django/
https://www.jianshu.com/p/1840035cb510
https://flower.readthedocs.io/en/latest/screenshots.html
接下来,我们需要把celery和django组合起来一起使用。
把django和celery进行组合
在main.py主程序中对django的配置文件进行加载
import os,django
from celery import Celery
# 初始化celery对象
app = Celery("luffy")
# 初始化django
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'luffyapi.settings.dev')
django.setup()
# 加载配置
app.config_from_object("mycelery.config")
# 自动注册任务
app.autodiscover_tasks(["mycelery.sms","mycelery.email"])
# 运行celery
# 终端下: celery -A mycelery.main worker -l info
在需要使用django配置的任务中,直接加载配置,所以我们把注册的短信发送功能,整合成一个任务函数,mycelery.sms.tasks,代码:
import json,logging
from mycelery.main import app
from ronglian_sms_sdk import SmsSDK
from django.conf import settings
from luffyapi.settings import constants
log = logging.getLogger("django")
@app.task(name="send_sms")
def send_sms(mobile,code):
"""发送短信"""
sdk = SmsSDK(
settings.SMS.get("accId"),
settings.SMS.get("accToken"),
settings.SMS.get("appId"),
)
try:
resp = sdk.sendMessage(settings.SMS.get("TempId"), mobile, (code, constants.SMS_EXPIRE_TIME // 60))
resp_data = json.loads(resp)
if resp_data.get("statusCode") != "000000":
raise Exception
except Exception as exc:
log.error("短信发送失败! 手机号:%s: %s" % (mobile,exc) )
raise Exception
在这个任务中,我们需要加载短信发送的sdk和相关的配置常量,所以我们可以直接把django中的短信发送模块和相关的常量配置文件直接剪切到当前sms任务目录中
mycelery/
├── config.py
├── __init__.py
├── main.py
└── sms/
├── __init__.py
├── tasks.py
再次启动项目即可。
最终在django里面,我们调用Celery来异步执行任务。需要完成2个步骤:
# 1. 声明一个和celery一模一样的任务函数,但是我们可以导包来解决
from mycelery.sms.tasks import send_sms
# 2. 调用任务函数,发布任务
send_sms.delay(mobile,code)
# send_sms.delay() 如果调用的任务函数没有参数,则不需要填写任何内容
四、定时任务
定时任务[crontab],主要是依靠:操作系统的定时计划或者第三方软件的定时执行
定时任务的常见场景:
1. 订单超时
2. 生日邮件[例如,每天凌晨检查当天有没有用户生日,有则发送一份祝福邮件]
3. 财务统计[例如,每个月的1号,把当月的订单进行统计,生成一个财务记录,保存到数据库中]
4. 页面缓存[例如,把首页设置为每隔5分钟生成一次缓存]
在django中要实现订单的超时取消,有以下三种方式:
1. Celery本身提供了定时任务的schedules执行机制
2. 第三方模块 django-crontab 定时任务
3. redis值空间回调事件[实际上就是监控字符串的键在过期时,让python自动执行对应的代码段或者方法函数]
https://blog.csdn.net/qq_42874635/article/details/107314161
Celery官方文档中关于定时任务使用的说明:
http://docs.celeryproject.org/en/latest/userguide/periodic-tasks.html
在实现定时任务之前,我们需要先简单使用一下。
我们需要新增一个任务目录,例如order
myceley/
├── sms/
│ ├── __init__.py
│ └── tasks.py
├── config.py
├── __init__.py
├── main.py
├── order/
│ ├── __init__.py
│ └── tasks.py
└── sms
在main.py中,注册任务目录【注意,接下来后面我们使用django的模型处理,所以必须对django的配置进行引入】
import os
from celery import Celery
# 1. 创建示例对象
app = Celery("luffy")
# 2. 加载配置
app.config_from_object("mycelery.config")
# 3. 注册任务[自动搜索并加载任务]
# 参数必须必须是一个列表,里面的每一个任务都是任务的路径名称
# app.autodiscover_tasks(["任务1","任务2"])
app.autodiscover_tasks(["mycelery.sms","mycelery.order"])
# 4. 在终端下面运行celery命令启动celery
# celery -A 主程序 worker --loglevel=info
# celery -A mycelery.main worker --loglevel=info
接下来,在order任务目录下, 创建固定名字的任务文件tasks.py,代码:
from my_celery.main import app
@app.task(name="check_order")
def check_order():
print("检查订单是否过期!!!")
接下来,我们需要把这个任务设置定时任务,所以需要借助Celery本身提供的Crontab模块。
在配置文件中,对定时任务进行注册:
# 任务队列地址
broker_url = 'redis://127.0.0.1:6379/15'
# 结果队列地址
result_backend = "redis://127.0.0.1:6379/14"
# 设置时区
timezone = 'Asia/Shanghai'
# 使用定时任务必须确保设置了时区
from .main import app
from celery.schedules import crontab
app.conf.beat_schedule = {
'check-order': {
'task': 'check_order', # 定时执行的任务
'schedule': 30.0, # 定时执行的频率,表示每30秒执行一次
# 'schedule': crontab(minute="*/5"), # 定时执行的频率,
# 'args': (16, 16) # 定时的任务参数
},
}
接下来,我们就可以重启Celery并启用Celery的定时任务调度器
先在终端下,运行celery的定时任务程序,以下命令:
celery -A mycelery.main beat # mycelery.main 是celery的主应用文件
然后再新建一个终端,运行以下命令,上面的命令必须先指定:
celery -A mycelery.main worker --loglevel=info
注意,使用的时候,如果有时区必须先配置好系统时区。
经过上面的测试以后,我们接下来只需改造上面的任务函数,用于判断修改订单是否超时。
要完成订单的任务功能,如果需要调用django框架的模型操作,那么必须针对django框架进行配置加载和初始化。
main.py,代码:
import os,django
from celery import Celery
# 初始化celery对象
app = Celery("luffy")
# 初始化django
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'luffyapi.settings.dev')
django.setup()
# 加载配置
app.config_from_object("mycelery.config")
# 自动注册任务
app.autodiscover_tasks(["mycelery.sms","mycelery.email","mycelery.order"])
# 运行celery
# 终端下: celery -A mycelery.main worker -l info
注意,因为在django中是有时区配置的,所以,我们在django框架配置中也要修改时区配置。
任务代码tasks.py的实现:
from mycelery.main import app
@app.task(name="check_order")
def check_order():
"""订单超时取消(业务逻辑)"""
pass
重新启动celery的定时任务模块和celery的主应用程序。
Celery异步分布队列的更多相关文章
- celery异步消息队列的使用
1.准备工作 1.1 流程图 2.环境安装 2.1.在Ubuntu中需要安装redis 安装redis $sudo apt-get update $sudo apt-get install redis ...
- 异步消息队列Celery
Celery是异步消息队列, 可以在很多场景下进行灵活的应用.消息中包含了执行任务所需的的参数,用于启动任务执行, suoy所以消息队列也可以称作 在web应用开发中, 用户触发的某些事件需要较长事件 ...
- 异步分布式队列Celery
异步分布式队列Celery 转载地址 Celery 是什么? 官网 Celery 是一个由 Python 编写的简单.灵活.可靠的用来处理大量信息的分布式系统,它同时提供操作和维护分布式系统所需的工具 ...
- 三.RabbitMQ之异步消息队列(Work Queue)
上一篇文章简要介绍了RabbitMQ的基本知识点,并且写了一个简单的发送和接收消息的demo.这一篇文章继续介绍关于Work Queue(工作队列)方面的知识点,用于实现多个工作进程的分发式任务. 一 ...
- Django使用Celery异步任务队列
1 Celery简介 Celery是异步任务队列,可以独立于主进程运行,在主进程退出后,也不影响队列中的任务执行. 任务执行异常退出,重新启动后,会继续执行队列中的其他任务,同时可以缓存停止期间接收 ...
- Django --- celery异步任务与RabbitMQ模块
一 RabbitMQ 和 celery 1 celery Celery 是一个 基于python开发的分布式异步消息任务队列,通过它可以轻松的实现任务的异步处理, 如果你的业务场景中需要用到异步任务, ...
- Celery异步任务重复执行(Redis as broker)
之前讲到利用celery异步处理一些耗时或者耗资源的任务,但是近来分析数据的时候发现一个奇怪的现象,即是某些数据重复了,自然想到是异步任务重复执行了. 查阅之后发现,到如果一个任务太耗时,任务完成时间 ...
- celery异步任务、定时任务
阅读目录 一 什么是Celery? 二 Celery的使用场景 三 Celery的安装配置 四 Celery异步任务 五Celery定时任务 六在Django中使用Celery 一 什么是Cele ...
- celery异步任务队列入门
参考: Celery入门 任务调度delay&apply_async celery 简要概述 Celery 中文手册 Celery动态添加定时任务 全网最细之Celery 4.x动态添加定时任 ...
- Java Design Demo -简单的队列-异步多任务队列(java android)
简单的单线程队列 -- 工作的时候遇到劣质打印机.给打印机发消息,打印机就会打印,如果在打印机还在打印的时候,就 再发消息打印,就会出现消息丢失.所以需要给上一个任务一些处理的间隔时间. 单线程的消息 ...
随机推荐
- Tensorflow 使用TPU训练
要用TPU训练tensorflow模型,只能使用静态图.也就是要先通过keras的sequential或者函数式定义模型,而不能直接使用重写的Model类.例子如下,其中包含层的自定义,以及子像素卷积 ...
- 这些 JavaScript 编码习惯,让你最大程度提高你的项目可维护性!
前言: 因为 JavaScript 语言是一门极其松散.极其自由的语言,这意味着我们可以随心所欲的操作它,这是他的优点,但同时也是它的缺点.在编码过程中,我们需要一种良好的规范或者习惯来保持应用程序的 ...
- Vue.js 插件
1.前言 vue的插件其实通过操作Vue这个对象,为其扩展新的功能.例如: // 1. 添加全局方法或 property Vue.myGlobalMethod = function () { // 逻 ...
- JavaScript 样式操作
1.类名操作 class类名以字符串的形式存储到标签和Dom元素的属性中,标签属性为class,Dom元素属性为className,两个属性是均支持读取和修改,修改其中的一个会同步至另一个属性 cla ...
- 设置QToolBar的Action图标之间的间隔
设置QToolBar的Action图标之间的间隔,网上搜索一大堆没用的,原来非常简单. toolBar->layout()->setContentsMargins(10, 10, 10, ...
- 如何使用图片压缩降低COS流量成本?
导语 本文将介绍如何通过[图片压缩]能力,让您降本增效的使用 COS ,文章将写得浅显易懂,旨在快速带领用户了解图片压缩的用法及带来的收益. **** 图片压缩为什么会让您降本增效?******** ...
- Premiere剪辑加速
使用AE或者Premire的时候,如果需要导出文件,有的文件还是挺大的,处理起来疯狂占用CPU,经常导致别的工作无法进行. 如果能够使用GPU进行压缩工作就好了,如果你用一块独立显卡,那么就可以正常使 ...
- 第 5 章 Debian 系统中可用的软件
目录 5.1. Debian GNU/Linux 收录了哪些类型的应用程序和开发工具? 5.2. 谁编写了所有这些软件? 5.3. 我应该如何获得一份 Debian 打包的程序的最新列表? 5.4. ...
- Python中定位元素包含文本信息的详细解析与代码示例
在Python编程中,特别是在进行网页自动化测试或数据抓取时,定位包含特定文本信息的元素是一个常见的需求.通过合适的工具和库,可以高效地查找和操作这些元素.本文将详细介绍如何在Python中定位包含文 ...
- Windows交叉编译MNN-3.0.0安卓版本库
一.写在前面 以下的步骤.流程都是基于MNN的文档,再结合自己的实践得出的,仅作为参考. 博主的环境是windows10专业版 MNN文档 MNN的Github仓库地址 二.下载MNN-3.0.0主库 ...