当前位置: 首页 > news >正文

异步框架Celery在Django中的运用

参考博客:https://www.cnblogs.com/pyedu/p/12461819.html

参考视频:01 celery的工作机制_哔哩哔哩_bilibili


定义:简单灵活、处理大量消息的分布式系统,专注于实时处理异步队列,支持任务调度

主要架构:

  1. 消息中间件:message broker 可以集成第三方消息中间件如Redis、RabbitMQ
  2. 任务执行单元:worker 是celery提供的执行的任务执行的单元,并发分布在分布式的系统节点中
  3. 任务执行结果存储:task result store来存储执行任务的结果,支持方式 redis、AMQP

同步请求: 顺序进行IO操作等待阻塞进程依次执行

异步请求:异步进行,当IO操作阻塞时放到执行单元中完成放到数据库中而不影响其他单元的执行,当主进程需要阻塞的进程结果时会向是数据库中取出该数据(即将耗时操作放到异步队列中不影响主进程的执行),继续向下进行

使用场景:

  1. 异步任务:将耗时操作任务提交到celery异步执行,如:发送短信、消息推送、音视频处理
  2. 定时任务:定时执行某件事情,如:每日数据统计

主要优点:

  • 简单:使用和维护不要配置文件,只需添加基本信息的配置
  • 高可用:在work和client网络连接丢失或失败时会自动进行重试
  • 快速:单个celery进程可每分钟处理百万级任务,只需要毫秒级的往返延迟
  • 灵活:可以扩展使用,自定义池的实现、序列化、日志记录、消费者、broker消息传输

安装:

pip install celery

实践案例:

"""
异步任务执行文件:celery_task.py
消费者模型
"""
import celery
import time
# task.py
import osos.environ.setdefault('FORKED_BY_MULTIPROCESSING', '1')backend='redis://127.0.0.1:6379/1'
broker='redis://127.0.0.1:6379/2'
cel=celery.Celery('test',backend=backend,broker=broker)
@cel.task
def send_email(name):print("向%s发送邮件..."%name)time.sleep(5)print("向%s发送邮件完成"%name)return "ok"@cel.task
def send_msg(name):print("向%s发送短信..."%name)time.sleep(5)print("向%s发送短信完成"%name)return "ok"""""
执行任务文件: produce_task.py
生成者模型
"""
from celery_task import send_email,send_msg
result = send_email.delay("yuan") # 当执行delay函数时会自动调用消息中间件的任务执行队列,放到任务执行单元中
print(result.id)
result = send_msg.delay("alex")
print(result.id)

先启动redis进程

 使用特定命令下发指令执行celery任务:

(注意celery5.0之前的命令是不一样的:celery worker -A celery_task -l info)

 先执行produce_task.py

返回ID: 

 fd27bc20-ccac-4855-9b3d-150708bad2a6
c07cb5b1-845a-44c4-963b-7ce3f92b98c8

 检查celery的异步队列查看执行结果

 注:当遇到以下情况

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "D:\python3\lib\site-packages\billiard\pool.py", line 361, in workloop
    result = (True, prepare_result(fun(*args, **kwargs)))
  File "D:\python3\lib\site-packages\celery\app\trace.py", line 664, in fast_trace_task
    tasks, accept, hostname = _loc
ValueError: not enough values to unpack (expected 3, got 0)
[2024-02-24 15:31:20,394: ERROR/MainProcess] Task handler raised error: ValueError('not enough values to unpack (expected 3, got 0)')

解决方法:

在消费者模型中添加以下代码

import os
os.environ.setdefault('FORKED_BY_MULTIPROCESSING', '1')

 查看异步执行的结果:

"""
查看任务执行结果: result.py
"""
from celery.result import AsyncResult
from celery_task import celasync_result=AsyncResult(id="fd27bc20-ccac-4855-9b3d-150708bad2a6", app=cel)if async_result.successful():result = async_result.get()print(result)# result.forget() # 将结果删除
elif async_result.failed():print('执行失败')
elif async_result.status == 'PENDING':print('任务等待中被执行')
elif async_result.status == 'RETRY':print('任务异常后正在重试')
elif async_result.status == 'STARTED':print('任务已经开始被执行')# 运行结果是上面执行返回的结果:
ok 

celery多任务结构下异步执行:注意celery_tasks的celery名字是固定,不然会报错

# celery
from celery import Celerycel = Celery('celery_demo',broker='redis://127.0.0.1:6379/1',backend='redis://127.0.0.1:6379/2',# 包含以下两个任务文件,去相应的py文件中找任务,对多个任务做分类include=['celery_tasks.task01','celery_tasks.task02'])# 时区
cel.conf.timezone = 'Asia/Shanghai'
# 是否使用UTC
cel.conf.enable_utc = False# task01
import time
from .celery import cel@cel.task
def send_email(res):time.sleep(5)return "完成向%s发送邮件任务"%res# task02
import time
from .celery import cel
@cel.task
def send_msg(name):time.sleep(5)return "完成向%s发送短信任务"%name# """"
执行任务文件: produce_task.py  和上面的celery_task保持在同一级目录
生成者模型
"""
from celery_tasks.task01 import send_email
from celery_tasks.task02 import send_msg# 立即告知celery去执行test_celery任务,并传入一个参数
result = send_email.delay('yuan')
print(result.id)
result = send_msg.delay('yuan')
print(result.id)
E:\desktop\my_drf\celerypro>celery -A celery_tasks worker -l info -P eventlet

运行结果:

 定时任务的配置:

# 更新produce_task 文件,增加定时任务
from celery_task import send_email
from datetime import datetime# 方式一
# v1 = datetime(2020, 3, 11, 16, 19, 00)
# print(v1)
# v2 = datetime.utcfromtimestamp(v1.timestamp())
# print(v2)
# result = send_email.apply_async(args=["egon",], eta=v2)  #  定时任务
# print(result.id)# 方式二
ctime = datetime.now()
# 默认用utc时间
utc_ctime = datetime.utcfromtimestamp(ctime.timestamp())
from datetime import timedelta
time_delay = timedelta(seconds=10)  # 当时时间10s后执行任务
task_time = utc_ctime + time_delay# 使用apply_async并设定时间
result = send_email.apply_async(args=["egon"], eta=task_time)
print(result.id)# 更新setting
cel.conf.beat_schedule = {# 名字随意命名'add-every-10-seconds': {# 执行tasks1下的test_celery函数'task': 'celery_tasks.task01.send_email',# 每隔2秒执行一次# 'schedule': 1.0,# 'schedule': crontab(minute="*/1"),'schedule': timedelta(seconds=6),# 传递参数'args': ('张三',)},# 'add-every-12-seconds': {#     'task': 'celery_tasks.task01.send_email',#     每年4月11号,8点42分执行#     'schedule': crontab(minute=42, hour=8, day_of_month=11, month_of_year=4),#     'args': ('张三',)# },
} 

运行结果:

 根据上述配置每6s执行task01发送邮件任务

注意:

# 周期性执行任务单元,要注意先启动beat进程而后执行worker单元
E:\desktop\my_drf\celerypro>celery -A celery_tasks beat
E:\desktop\my_drf\celerypro>celery -A celery_tasks worker -l info -P eventlet注意: 当打开beat后而若没有打开worker执行单元会导致beat进程不断向数据库中加入数据

 

  查看redis堆积的数据方法:cmd命令如下

 python脚本实现:

 celery结合django中集成的运用

# tasks
# celery的任务必须写在tasks.py的文件中,别的文件名称不识别!!!
from mycelery.main import app
import timeimport logging
log = logging.getLogger("django")@app.task  # name表示设置任务的名称,如果不填写,则默认使用函数名做为任务名
def send_sms(mobile):"""发送短信"""print("向手机号%s发送短信成功!"%mobile)time.sleep(5)return "send_sms OK"@app.task  # name表示设置任务的名称,如果不填写,则默认使用函数名做为任务名
def send_sms2(mobile):print("向手机号%s发送短信成功!" % mobile)time.sleep(5)return "send_sms2 OK"# config
broker_url = 'redis://127.0.0.1:6379/15'
result_backend = 'redis://127.0.0.1:6379/14'# main
# 主程序
import os
from celery import Celery
# 创建celery实例对象
app = Celery("sms")
# import os
os.environ.setdefault('FORKED_BY_MULTIPROCESSING', '1') # 注意: 默认配置要这样配置,下列的配置会找不到组件导致失败
# 把celery和django进行组合,识别和加载django的配置文件
# os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'celerypro.settings.dev')
# os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings.local")# 通过app对象加载配置
app.config_from_object("mycelery.config")# 加载任务
# 参数必须必须是一个列表,里面的每一个任务都是任务的路径名称
# app.autodiscover_tasks(["任务1","任务2"])
app.autodiscover_tasks(["mycelery.sms",])# view 
from django.shortcuts import render,HttpResponse
from mycelery.sms.tasks import send_sms,send_sms2
from datetime import timedeltafrom datetime import datetime
def test(request):################################# 异步任务# 1. 声明一个和celery一模一样的任务函数,但是我们可以导包来解决send_sms.delay("110")send_sms2.delay("119")# send_sms.delay() #  如果调用的任务函数没有参数,则不需要填写任何内容################################# 定时任务ctime = datetime.now()# 默认用utc时间utc_ctime = datetime.utcfromtimestamp(ctime.timestamp())time_delay = timedelta(seconds=3) # 3s 发送消息task_time = utc_ctime + time_delayresult = send_sms.apply_async(["911", ], eta=task_time)print(result.id)return HttpResponse('ok')

启动Celery的命令

# 强烈建议切换目录到mycelery根目录下启动
# E:\desktop\my_drf\celerypro>celery -A mycelery.main worker --loglevel=info

运行结果:

相关文章:

异步框架Celery在Django中的运用

参考博客:https://www.cnblogs.com/pyedu/p/12461819.html 参考视频:01 celery的工作机制_哔哩哔哩_bilibili 定义:简单灵活、处理大量消息的分布式系统,专注于实时处理异步队列,支持任务调度 主要架构: …...

YOLOv5代码解读[02] models/yolov5l.yaml文件解析

文章目录 YOLOv5代码解读[02] models/yolov5l.yaml文件解析yolov5l.yaml文件检测头1--->耦合头检测头2--->解耦头检测头3--->ASFF检测头Model类解析parse_model函数 YOLOv5代码解读[02] models/yolov5l.yaml文件解析 yolov5l.yaml文件 # YOLOv5 🚀 by Ult…...

智能搬运机器人|海格里斯将如何持续推进工业和物流的智能化升级与发展?

存取、搬运、分拣是物流行业中的通用功能,但具体到每个行业又十分不同,例如:新能源电池领域,它所搬运的东西是电池,50KG~200KG;快递行业领域,所要处理的物料是那种扁平件和信封等等,…...

linux之前后端项目部署与发布

目录 前言 简介 一、安装Nginx 二、后端部署 2.1多个tomcat负载均衡 2.2 负载均衡 2.3 后端项目部署 三、前端部署 1.解压前端 2.Nginx配置文件修改 3.IP域名映射 4.重启Nginx服务 前言 上篇博主已经讲解过了单机项目的部署linux之JAVA环境配置JDK&Tomcat&a…...

Python 高级语法:一切皆对象

1 “一切皆对象”是一种核心设计哲学 在编程领域,特别是面向对象编程(OOP)中,“一切皆对象”是一种核心设计哲学。这种哲学主张,无论是数据、函数、还是更复杂的结构,都可以被视为对象,并赋予…...

python jupyter notebook打开页面方便使用

如果没安装jupyter, 请安装: pip install jupyter notebook 运行jupyter notebook jupyter-notebook...

音视频开发之旅(69)-SD图生图

目录 1. 效果展示 2. ControlNet介绍 3. 图生图流程浅析 4. SDWebui图生图代码流程 5. 参考资料 一、效果展示 图生图的应用场景非常多,比较典型的应用场景有风格转化(真人与二次元)、线稿上色、换装和对图片进行扩图等,下面…...

數據集成平台:datax將hive數據步到mysql(全部列和指定列)

數據集成平台:datax將hive數據步到mysql(全部列和指定列) 1.py腳本 傳入參數: target_database:數據庫 target_table:表 target_columns:列 target_positions:hive列的下標&#x…...

pikachu靶场-File Inclusion

介绍: File Inclusion(文件包含漏洞)概述 文件包含,是一个功能。在各种开发语言中都提供了内置的文件包含函数,其可以使开发人员在一个代码文件中直接包含(引入)另外一个代码文件。 比如 在PHP中,提供了&…...

[今天跟AI聊聊职场] ~你能接受你的直接领导能力不如你,年纪还比你小很多吗?

知乎问题: 弟弟今年35岁,刚换了一份工作,直接领导小A比他小5岁,各方面经验没有他成熟。难的工作都是弟弟在做,功劳都被直接领导小A抢走了,有时候还要被直接领导小A打压。弟弟感觉升职加薪无望。现在找工作不…...

网络原理TCP之“三次握手“

TCP内核中的建立连接 众所周知,TCP是有连接的. 当我们在客户端敲出socket new Socket(serverIp,severPort)时,就在系统内核就在建立连接 真正建立连接是在系统内核中建立的,我们程序员只是调用相关的api. 在此处,我们把TCP的建立连接称为三次握手. 系统在内核建立连接时如上…...

990-03产品经理与程序员:什么是 IT 与业务协调以及为什么它很重要?

What is IT-business alignment and why is it important? 什么是IT-业务一致性?为什么它很重要? It’s more important than ever that IT and the business operate from the same playbook(剧本). So why do so many organizations struggle to ach…...

Java Web(七)__Tomcat(二)

Tomcat工作模式 Tomcat作为Servlet容器,有以下三种工作模式。 1)独立的Servlet容器,由Java虚拟机进程来运行 Tomcat作为独立的Web服务器来单独运行,Servlet容器组件作为Web服务器中的一部分而存在。这是Tomcat的默认工作模式。…...

【项目实战】帮美女老师做一个点名小程序(Python tkinter)

前言 博主有一个非常漂亮的老师朋友😍。最近,她急需一个能够实现随机点名的小程序,而博主正好擅长这方面的技术🤏。所以,今天博主决定为她制作一个专门用于点名的小程序💪。 博主在美女老师面前吹完牛皮之…...

Elasticsearch 去重后求和

标题的要求可以用如下 SQL 表示 select sum(column2) from (select distinct(column1),column2 from table)t 要如何用 DSL 实现呢,先准备下索引和数据 PUT test_index {"mappings": {"properties": {"column1": {"type"…...

考研数学——高数:函数与极限(3)

函数的连续性与间断点 函数的连续性 左连续 右连续 区间上的连续性 在xo处连续 函数的间断点 第一类间断点(左右极限都存在) 可去间断点: f(xo-0)= f(xo+0) 跳跃间断点: f(xo-0)≠ f(xo+0) 第二类间断点(震荡间断点、无穷间断点)...

LeetCode49 字母异位词分组

LeetCode49 字母异位词分组 在这篇博客中,我们将探讨 LeetCode 上的一道经典算法问题:字母异位词分组。这个问题要求将给定的字符串数组中的字母异位词组合在一起,并以任意顺序返回结果列表。 问题描述 给定一个字符串数组 strs&#xff0…...

【Python】Windows本地映射远程Linux服务器上的端口(解决jupyter notebook无法启动问题)

创作日志: 学习深度学习不想在本地破电脑上再安装各种软件,我就用实验室的服务器配置环境,启动jupyter notebook时脑子又瓦特了,在自己Windows电脑上打开服务器提供的网址,那肯定打不开啊,以前在其它电脑上…...

C++面试:用户态和内核态的基本概念、区别

目录 一、基本概念 概念: 区别: 二、Windows示例 基础介绍 用户态到内核态的切换过程: 程序实例 三、Linux示例 特权级别: 用户态到内核态的切换过程: 调度和中断处理: 程序实例 总结 在操作系…...

Vue计算属性computed()

1. 计算属性定义 获取计算属性值 <div>{{ 计算属性名称}}</div>创建计算属性 let 定义的属性ref/reactive....let 计算属性名称 computed(() > {//这里写函数式,函数式里面包含定义属性//只有这个包含的定义属性被修改时才出发此函数式//通过计算属性名称co…...

Linux 文件类型,目录与路径,文件与目录管理

文件类型 后面的字符表示文件类型标志 普通文件&#xff1a;-&#xff08;纯文本文件&#xff0c;二进制文件&#xff0c;数据格式文件&#xff09; 如文本文件、图片、程序文件等。 目录文件&#xff1a;d&#xff08;directory&#xff09; 用来存放其他文件或子目录。 设备…...

解锁数据库简洁之道:FastAPI与SQLModel实战指南

在构建现代Web应用程序时&#xff0c;与数据库的交互无疑是核心环节。虽然传统的数据库操作方式&#xff08;如直接编写SQL语句与psycopg2交互&#xff09;赋予了我们精细的控制权&#xff0c;但在面对日益复杂的业务逻辑和快速迭代的需求时&#xff0c;这种方式的开发效率和可…...

最新SpringBoot+SpringCloud+Nacos微服务框架分享

文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的&#xff0c;根据Excel列的需求预估的工时直接打骨折&#xff0c;不要问我为什么&#xff0c;主要…...

使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装

以下是基于 vant-ui&#xff08;适配 Vue2 版本 &#xff09;实现截图中照片上传预览、删除功能&#xff0c;并封装成可复用组件的完整代码&#xff0c;包含样式和逻辑实现&#xff0c;可直接在 Vue2 项目中使用&#xff1a; 1. 封装的图片上传组件 ImageUploader.vue <te…...

sqlserver 根据指定字符 解析拼接字符串

DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...

vue3 定时器-定义全局方法 vue+ts

1.创建ts文件 路径&#xff1a;src/utils/timer.ts 完整代码&#xff1a; import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...

IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)

文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...

视频行为标注工具BehaviLabel(源码+使用介绍+Windows.Exe版本)

前言&#xff1a; 最近在做行为检测相关的模型&#xff0c;用的是时空图卷积网络&#xff08;STGCN&#xff09;&#xff0c;但原有kinetic-400数据集数据质量较低&#xff0c;需要进行细粒度的标注&#xff0c;同时粗略搜了下已有开源工具基本都集中于图像分割这块&#xff0c…...

初探Service服务发现机制

1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能&#xff1a;服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源&#xf…...

Golang——6、指针和结构体

指针和结构体 1、指针1.1、指针地址和指针类型1.2、指针取值1.3、new和make 2、结构体2.1、type关键字的使用2.2、结构体的定义和初始化2.3、结构体方法和接收者2.4、给任意类型添加方法2.5、结构体的匿名字段2.6、嵌套结构体2.7、嵌套匿名结构体2.8、结构体的继承 3、结构体与…...