分布式异步任务框架celery

news/2024/5/10 18:48:24

Celery介绍

github地址:GitHub - celery/celery: Distributed Task Queue (development branch)

文档地址:Celery - Distributed Task Queue — Celery 5.3.6 documentation

1.1 Celery是什么

celery时一个灵活且可靠的处理大量消息的分布式系统,可以在多个节点之间处理某个任务

celery时一个专注于实时处理的任务队列,支持任务调度

celery是开源的,有很多的使用者

celery完全基于python语言编写的

celery本质上是一个【分布式的异步任务调度框架】,类似于Apache的airflow

celery只是用来调度任务的,但是它本身并不具备存储任务的功能,而调度任务的时候肯定是要把任务存起来,因此要使用celery的话,还需要搭配一些具有存储、访问功能的工具,比如:消息队列、Redis缓存、数据库等。官方推荐是消息队列RabbitMQ,我们使用Redis

同步调用函数 --》add--》执行5s钟--》数据返回了

异步调用函数--》add--》执行5s钟--》执行完的数据,找个地方存起来

调用方--》去存的地方看一下--》任务有没有执行完

1.2 应用场景

1)异步任务

 视频转码、邮件发送、消息推送等一些耗时操作

2)定时任务

定时推送消息、定时爬取一些数据、定时统计一些数据

3)延时任务

提交任务后,等一段时间再执行任务

1.3 celery架构

celery架构,它采用典型的生产者-消费者模式,主要由以下部分组成

生产者生产---消费者进行消费

producer:它负责把任务提交到broker钟

celery Beat:会读取文件、周期性的向broker中提交任务

broker:消息中间件,放任务的地点,celery本身不提供,借助redis等消息队列

worker:工人、消费者,负责从消息中间件中取出任务--》执行

backend:worker执行完,会有结果,结果存储再backend,celery不提供,借助redis等消息队列。

Celery使用

2.1 安装

pip install celery

使用redis作为消息队列

pip install redis

如果是Windows系统还需要安装eventlet

pip install eventlet

2.2 使用

创建main.py文件

import timefrom celery import Celery# 任务消息队列
broker = "redis://127.0.0.1:6379/1"
# 结果消息队列
backend = "redis://127.0.0.1:6379/2"
# 实例化app对象
app = Celery("demo", broker=broker, backend=backend)# 编写任务
@app.task  # 被装饰器装饰了,才是celery任务
def add(a, b):print("a+b的结果是", a + b)time.sleep(1)  # 模拟耗时return a + b

创建add_task.py文件编写消费者代码

"""这个程序用来提交任务 producer"""
from main import add# # 同步任务
# res = add(1, 2)
# print(res)
# 异步任务
# 像消息队列中提交了一个任务,计算1+5的任务,但是没有执行  ceec680b-e0fb-4636-9244-1fa7ca0c570c
res = add.delay(1, 5)  # 没有耗时,直接返回,但是没有返回值,而是返回一个uuid号
print(res)
# 启动worker 再终端使用命令启动,执行完成后会把结果存到redis的2库中
# win :celery -A main worker -l info -P eventlet
# mac/linux:celery -A main worker -l info

启动worker需要再终端下方进行启动

win :celery -A main worker -l info -P eventlet
mac/linux:celery -A main worker -l info

如果报错celery库找不到的问题,使用python -m celery -A main worker -l info -P eventlet进行启动

2.3 包结构

后续的项目越来越大,task任务越来越多,希望把任务拆分再多个py文件中

目录结构

celery.py

import timefrom celery import Celery# 任务消息队列
broker = "redis://127.0.0.1:6379/1"
backend = "redis://127.0.0.1:6379/2"
# 实例化app对象
app = Celery("demo", broker=broker, backend=backend,include=['celery_task.crawl_task', 'celery_task.user_task', 'celery_task.order_task'])# 任务分到不同的py文件中

user_task.py

import time
from .celery import app@app.task
def send_email(to):print("发送邮件")time.sleep(3)print(f"向{to}发送邮件成功")return f"向{to}发送邮件成功"

order_task.py

import time
from .celery import app@app.task
def pay_order():print("开始下单")time.sleep(5)print("下单完成")return "下单完成"

crawl_task.py

import time
from .celery import app@app.task
def crawl_baidu():print("开始爬虫百度")time.sleep(2)print("爬虫完毕百度")return "爬虫完毕百度"@app.task
def crawl_dewu():print("开始爬虫得物")time.sleep(2)print("爬虫完毕百度")return "爬虫完毕得物"

add_task.py

from celery_task.crawl_task import crawl_baidures = crawl_baidu.delay()  # 没有参数,这里就不传
print(res)  # 得到uuid

get_result.py(查询是否被执行)

from .celery_task.celery import app
from celery.result import AsyncResultid = "你的任务uuid"
if __name__ == '__main__':result = AsyncResult(id=id, app=app)if result.successful():result = result.get()print(result)elif result.failed():print("任务失败")elif result.status == "PENDING":print("任务等待被执行")elif result.status == "RETRY":print("任务异常后正在重试")elif result.status == "STARTED":print("任务已经开始被执行")

启动worker命令

celery -A celery_task(包名) worker -l info -P eventlet

异步任务-延时任务-定时任务

异步任务

上述介绍的均为异步任务

使用delay()

延时任务

from celery_task.user_task import send_email
from datetime import datetime, timedeltaeta = datetime.utcnow() + timedelta(seconds=5)  # 默认时区为utc时区
res = send_email.apply_async(args=['邮箱'], eta=eta)
print(res)

apply_async(args=['参数'],eta=延时时间)

如果延迟任务提交了,但是worker没启动,等延迟的时间,worker再启动,任务会立马启动

定时任务

在celery.py中

import timefrom celery import Celery# 任务消息队列
broker = "redis://127.0.0.1:6379/1"
backend = "redis://127.0.0.1:6379/2"
# 实例化app对象
app = Celery("demo", broker=broker, backend=backend,include=['celery_task.crawl_task', 'celery_task.user_task', 'celery_task.order_task'])# 任务分到不同的py文件中# 加入定时任务
# 指定了时区,中国时区,以后延时任务
app.conf.timezone = "Asia/Shanghai"
app.conf.enable_utc = False
# 每隔5s爬取百度
from datetime import datetime, timedeltaapp.conf.beat_schedule = {'low-task': {'task': 'celery_task.crawl_task.crawl_baidu','schedule': timedelta(seconds=5), # 每5秒发送一次'args': ()  # 参数}
}
# 必须启动beat

启动beat命令

celery -A celery_task beat -l info

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.tangninghui.cn.cn/item-12150.htm

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

基于UDP的网络聊天室

1、如果有用户登录&#xff0c;其他用户可以收到这个人的登录信息 2、如果有人发送信息&#xff0c;其他用户可以收到这个人的群聊信息 3、如果有人下线&#xff0c;其他用户可以收到这个人的下线信息 4、服务器可以发送系统信息 服务器 #include<myhead.h>typedef s…

Linux 进程信号:产生信号

目录 一、通过终端按键产生信号 1、signal()函数 2、核心转储 3、ulmit命令 二、调用系统函数向进程发信号 1、kill()函数 2、raise()函数 3、abort()函数 三、发送信号的过程 读端关闭、写端继续写入的情况 如何理解软件条件给进程发送信号: 四、软件条件产生信…

几个常用的控件(2)

目录 一、单选按钮Radiobutton和RadioButtonList 1、Radiobutton控件 &#xff08;1&#xff09;button控制方式 &#xff08;2&#xff09;Radiobutton控制方式 2、RadiobuttonList控件 二、列表框ListBox和下拉列表DropdownList 1、ListBox 2、DropdownList 三、面板…

第八章贪心算法——理论基础,分发饼干题目

目录 概念 什么时候使用 题目举例 分发饼干 力扣题号&#xff1b;455. 分发饼干 - 力扣&#xff08;LeetCode&#xff09; 题目描述 示例 1: 示例 2: 解法一&#xff1a;排序暴力 解法二&#xff1a;贪心 思路 代码实现 总结 概念 贪心算法是一种在每一步选择中都采…

什么算法可以进行小语种的OCR?

对于小语种的OCR识别&#xff0c;可以采用以下算法和技术&#xff1a; 1. 迁移学习&#xff08;Transfer Learning&#xff09;&#xff1a;使用在大语种上预训练好的OCR模型&#xff0c;并通过迁移学习的方式对小语种进行微调。这样可以利用大语种上已有的丰富数据和知识&…

HAL STM32G4 +ADC手动触发采集+各种滤波算法实现

HAL STM32G4 ADC手动触发采集各种滤波算法实现 &#x1f4cd;相关篇《HAL STM32G4 TIM1 3路PWM互补输出VOFA波形演示》 ✨本篇内容也是继欧拉电子相关无刷电机驱动控制学习的相关基础内容。仅作为个人笔记记录使用。 &#x1f4cd;感谢网友提供的相关内容《基于STM32的ADC采样及…