《Python实战进阶》No 9:使用 Celery 实现异步任务队列

第9集:使用 Celery 实现异步任务队列


引言

在现代 Web 应用中,许多操作(如发送邮件、处理文件上传、执行复杂计算等)可能需要耗费较长时间。如果这些操作直接在主线程中执行,会导致用户请求阻塞,降低用户体验。为了解决这一问题,我们可以使用 Celery 来实现异步任务队列。

Celery 是一个强大的分布式任务队列框架,支持 Python 编写的异步任务调度和后台任务处理。本篇将详细介绍如何使用 Celery 构建异步任务队列,并结合实际案例展示其在 Flask 和 Django 项目中的应用。
在这里插入图片描述


1. 什么是 Celery?

Celery 是一个基于消息队列的任务调度工具,它允许你将耗时的任务从主线程中分离出来,交由后台进程异步执行。Celery 的核心组件包括:

  • 任务生产者(Producer):负责创建任务并将其发送到消息队列。
  • 消息代理(Broker):用于存储任务队列,常见的代理有 RabbitMQ 和 Redis。
  • 任务消费者(Worker):从消息队列中获取任务并执行。

2. 安装与配置
2.1 安装 Celery

首先,确保你的环境中已安装 Celery 和消息代理(这里以 Redis 为例):

pip install celery redis
2.2 配置 Redis

Redis 是 Celery 常用的消息代理之一。你可以通过以下命令安装 Redis:

sudo apt install redis-server

启动 Redis 服务:

sudo systemctl start redis

验证 Redis 是否正常运行:

redis-cli ping
# 如果返回 "PONG",说明 Redis 已成功启动。

3. 使用 Celery 的基本流程

以下是使用 Celery 的基本步骤:

  1. 创建 Celery 应用实例。
  2. 定义异步任务。
  3. 启动 Celery Worker。
  4. 在主程序中调用任务。

接下来我们将通过一个简单的示例演示这些步骤。


4. 示例:异步发送邮件

假设我们需要实现一个功能:当用户注册时,系统会向用户发送一封欢迎邮件。由于发送邮件是一个耗时操作,我们将其封装为 Celery 异步任务。

4.1 创建 Celery 应用

在项目根目录下创建 celery_app.py 文件:

from celery import Celery# 创建 Celery 应用实例
app = Celery('tasks', broker='redis://localhost:6379/0')# 定义异步任务
@app.task
def send_welcome_email(user_email):print(f"Sending welcome email to {user_email}...")# 模拟发送邮件的耗时操作import timetime.sleep(5)print(f"Welcome email sent to {user_email}")
4.2 启动 Celery Worker

在终端中启动 Celery Worker:

celery -A celery_app worker --loglevel=info

这将启动一个 Celery Worker,监听任务队列并执行任务。

4.3 调用异步任务

在主程序中调用 send_welcome_email 任务。以下是一个 Flask 示例:

from flask import Flask, request, jsonify
from celery_app import send_welcome_emailapp = Flask(__name__)@app.route('/register', methods=['POST'])
def register():user_email = request.json.get('email')if not user_email:return jsonify({"error": "Email is required"}), 400# 异步调用任务send_welcome_email.delay(user_email)return jsonify({"message": "Registration successful. Welcome email will be sent shortly."}), 200if __name__ == '__main__':app.run(debug=True)
4.4 测试

启动 Flask 应用:

python app.py

使用 Postman 或 curl 发送 POST 请求:

curl -X POST http://127.0.0.1:5000/register -H "Content-Type: application/json" -d '{"email": "test@example.com"}'

你会看到 Celery Worker 输出日志,表明任务正在异步执行。


5. Celery 的高级特性
5.1 定时任务

Celery 支持定时任务,可以用来定期执行某些操作。例如,每天凌晨清理过期数据:

  1. 安装 Celery 的扩展包 celery[redis]celery[schedule]
  2. 配置定时任务:
from celery.schedules import crontabapp.conf.beat_schedule = {'cleanup-every-midnight': {'task': 'tasks.cleanup_expired_data','schedule': crontab(hour=0, minute=0),},
}
  1. 启动 Celery Beat:
celery -A celery_app beat --loglevel=info
5.2 任务结果存储

默认情况下,Celery 不会存储任务的执行结果。如果需要查看任务状态或结果,可以配置结果后端(如 Redis 或数据库):

app = Celery('tasks', broker='redis://localhost:6379/0', backend='redis://localhost:6379/0')

然后可以通过 AsyncResult 获取任务结果:

from celery.result import AsyncResultresult = AsyncResult(task_id, app=app)
print(result.status)  # 查看任务状态
print(result.result)  # 查看任务结果

6. 在 Django 中使用 Celery

如果你使用的是 Django,可以通过 django-celery-resultsdjango-celery-beat 扩展来简化 Celery 的集成。

  1. 安装依赖:
pip install django-celery-results django-celery-beat
  1. 配置 settings.py
INSTALLED_APPS += ['django_celery_results','django_celery_beat',
]CELERY_BROKER_URL = 'redis://localhost:6379/0'
CELERY_RESULT_BACKEND = 'redis://localhost:6379/0'
  1. 迁移数据库:
python manage.py migrate
  1. 定义任务并在视图中调用,与 Flask 类似。

7. 总结

通过本篇教程,我们学习了如何使用 Celery 构建异步任务队列,并通过实际案例展示了其在 Flask 和 Django 项目中的应用。Celery 的强大之处在于其灵活性和可扩展性,无论是简单的异步任务还是复杂的分布式任务调度,它都能胜任。

下一集我们将探讨 Web 安全性,重点讲解如何防止 SQL 注入、XSS 和 CSRF 攻击,敬请期待!


参考资料
  • Celery 官方文档
  • Redis 官方文档
  • Flask 官方文档
  • Django 官方文档

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ue5 创建多列StreeView的方法与理解

创建StreeView的多列样式怎么就像是创建单行单列差不多?貌似就是在单行单列中加入了多列widget? 目录结构: 必备条件 StreeView的多列创建需要的必备条件: 数据基类 CustomItemBase #pragma once /* ---------------------------------- | Name | Value …

Spring的下载与配置

1. 下载spring开发包 下载地址:https://repo.spring.io/webapp/#/artifacts/browse/simple/General/libs-release-local/org/springframework/spring 打开之后可以看到有很多版本供选择,因为视频教程用的是4.2.4版本,于是我也选择这个 右键…

Python + requests实现接口自动化框架

🍅 点击文末小卡片,免费获取软件测试全套资料,资料在手,涨薪更快 为什么要做接口自动化框架 1、业务与配置的分离 2、数据与程序的分离;数据的变更不影响程序 3、有日志功能,实现无人值守 4、自动发送测…

Linux——基本指令

我们今天学习Linux最基础的指令 ls 指令 语法: ls [选项] [⽬录或⽂件] 功能:对于⽬录,该命令列出该⽬录下的所有⼦⽬录与⽂件。对于⽂件,将列出⽂件名以及其他信 息。 命令中的选项,一次可以传递多个 &#xff0c…

【Godot4.3】自定义简易菜单栏节点ETDMenuBar

概述 Godot中的菜单创建是一个复杂的灾难性工作,往往无从下手,我也是不止一次尝试简化菜单的创建。 从自己去年的发明“简易树形数据”用于简化Tree控件获得灵感,于是尝试编写了用于表示菜单数据的EasyMenuData类,以及对应的纯文…

esp32串口通信

1、查看esp32的引脚图,寻找对应的串口 根据原理图,芯片上有3个串口(UART0, UART1和UART2),但是UART1没有引出引脚。其中UART0(GPIO3用于U0RXD,GPIO1用于U0TXD)用作下载、调试串口,引脚不可改变&…

内部静态类和非内部静态类的区别

目录 问题: 原理: 外部类与非内部静态类 外部类与静态内部类 加载顺序 总结: 1.非静态内部类依赖于外部类的实例,而静态内部类不依赖于外部类的实例。 2.非静态内部类可以访问外部类的实例变量和方法,而静态内部…

Redis分布式锁的实现(Redission)

写在前面 本人在学习Redis过程中学习到分布式锁时太多困惑和疑难杂点 需要总结梳理思路 以下思路都是最简单最基本的思路 主要用到Redission工具类 会涉及到看门狗机制等 本文内容部分引自Javaguide,小林coding等热门八股 用于个人学习用途 分布式锁介绍 对于单机多线程来说…

【愚公系列】《Python网络爬虫从入门到精通》038-SQLite数据库

标题详情作者简介愚公搬代码头衔华为云特约编辑,华为云云享专家,华为开发者专家,华为产品云测专家,CSDN博客专家,CSDN商业化专家,阿里云专家博主,阿里云签约作者,腾讯云优秀博主,腾讯云内容共创官,掘金优秀博主,亚马逊技领云博主,51CTO博客专家等。近期荣誉2022年度…

【开源免费】基于SpringBoot+Vue.JS网络海鲜市场系统(JAVA毕业设计)

本文项目编号 T 222 ,文末自助获取源码 \color{red}{T222,文末自助获取源码} T222,文末自助获取源码 目录 一、系统介绍二、数据库设计三、配套教程3.1 启动教程3.2 讲解视频3.3 二次开发教程 四、功能截图五、文案资料5.1 选题背景5.2 国内…

JDK17安装方法/如何安装JDK17/环境变量配置

双击安装 我们这里安装jdk17 然后更改jdk目录 jdk环境变量配置 右键——>此电脑——>高级系统设置——>环境变量 当前用户的环境变量,另外有一个系统变量。 一般我们配置系统环境变量 一、配置JAVA_HOME 这里我们配置一个JAVA_HOME 我这里先前的jdk…

python集合set的常用方法

目录 集合的定义 集合的基础操作 多个集合之间的操作 集合的for循环 集合的定义 集合的基础操作 集合.add(元素) 添加新元素 集合.pop() 从集合中随机取出一个元素 集合.clear() 清空集合 集合.remove(元素) 移除元素 #定义集合,集合自动去重了 set1{"春"…

看得见摸得着的AI:具身智能

“如果Siri有手有脚,你的生活会变成什么样?” 想象一下: • 你家的扫地机器人不再横冲直撞,而是像猫咪一样轻巧绕过桌脚 • 手机里的语音助手能“摸”到你发烧的额头,主动帮你叫医生 • 工厂里的机械臂会边干活边学习&…

ES、OAS、ERP、电子政务、企业信息化(高软35)

系列文章目录 ES、OAS、ERP、电子政务、企业信息化 文章目录 系列文章目录前言一、专家系统(ES)二、办公自动化系统(OAS)三、企业资源规划(ERP)四、典型信息系统架构模型1.政府信息化和电子政务2.企业信息…

【算法学习之路】4.简单数论(4)

简单数论(4) 前言三.高精度1.什么是高精度2.解决办法 精度乘除法一.精度乘法1.数据的存储2.步骤3.例题:高精度乘法 二.精度除法1.例子2.步骤3.例题:高精度除法 前言 我会将一些常用的算法以及对应的题单给写完,形成一套…

Linux 动静态库和_make_进度条(一)

文章目录 一、如何理解条件编译二、动静态库1. 理论2. 实践3. 解决普通用户的sudo问题4. 技术上理解库 三、make和make_file 一、如何理解条件编译 1. gcc code.c -o code -DM 命令行级别的宏定义预处理的本质就是修改编辑我们的文本代码 头文件展开到源文件中去注释宏替换条…

基于springboot+vue的拖恒ERP-物资管理

开发语言:Java框架:springbootJDK版本:JDK1.8服务器:tomcat7数据库:mysql 5.7(一定要5.7版本)数据库工具:Navicat11开发软件:eclipse/myeclipse/ideaMaven包:…

Leetcode-853. Car Fleet [C++][Java]

目录 一、题目描述 二、解题思路 Leetcode-853. Car Fleethttps://leetcode.com/problems/car-fleet/description/ 一、题目描述 There are n cars at given miles away from the starting mile 0, traveling to reach the mile target. You are given two integer array …

Vue核心知识:动态路由实现完整方案

在Vue中实现动态路由,并结合后端接口和数据库表设计,是一个复杂的项目,需要多个技术栈和步骤的配合。以下将详细描述整个实现过程,包括数据库设计、后端接口设计、前端路由配置以及如何实现动态路由的功能。 目录 一、需求分析二…

CMU15445(2023fall) Project #4 - Concurrency Control踩坑历程

把树木磨成月亮最亮时的样子, 就能让它更快地滚下山坡, 有时会比骑马还快。 完整代码见: SnowLegend-star/CMU15445-2023fall: Having Conquered the Loftiest Peak, We Stand But a Step Away from Victory in This Stage. With unwavering…