Celery介绍、安装、基本使用

一、Celery服务

什么是Celery:

Celery是一个简单、灵活且可靠的,处理消息的分布式系统

  • Celery可以用来做什么:

    • 异步任务
    • 定时任务
    • 延迟任务

Celery的运行原理:

  • 可以不依赖任何服务,通过自身命令,启动服务
  • celery服务为其他项目服务提供异步解决任务需求
# 注:会有两个服务同时运行
- 项目服务
- celery服务
项目服务将需要异步处理的任务交给celery服务,celery就会在需要时异步完成项目的需求 '''
人是一个独立运行的服务 | 医院也是一个独立运行的服务
正常情况下,人可以完成所有健康情况的动作,不需要医院的参与;但当人生病时,就会被医院接收,解决人生病问题
人生病的处理方案交给医院来解决,所有人不生病时,医院独立运行,人生病时,医院就来解决人生病的需求 '''

1、celery架构

  • 消息中间件:broker

    • 提交的任务【函数】都放在这里, celery本身不能提供消息中间件
    • 需要借助于第三方: redis或rabbitmq
  • 任务执行单元:worker

    • 真正执行任务的的地方,一个个进程中执行函数
  • 结果储存:backend

    • 函数return的结果都存储在这里, celery本身不提供结果存储
    • 需要借助于第三方: redis或rabbitmq

使用场景:

  • 异步执行:解决耗时任务
  • 延迟执行:解决延迟任务
  • 定时执行:解决周期任务

2、celery快速使用

Celery不支持在windows上直接运行,通过eventlet支持在win上运行

安装:

pip install celery
pip install eventlet # windows需要安装

快速使用:

- 1、第一步:创建一个py文件(main.py),用于实例化celery对象,编写需要执行的函数
# 1、导入模块
from celery import Celery # 2、指定briker,用于存放提交的异步任务
broker = 'redis://127.0.0.1:6379/1'
# 3、指定backend,用于存放函数执行结束的结果
backend = 'redis://127.0.0.1:6379/2'
# 实例化celery对象
app = Celery('test', broker=broker, backend=backend) # 编写一个函数,装饰上celery对象
@app.task
def add(a, b):
import time
time.sleep(3)
print('add函数执行完成')
return a + b - 2、第二步:再次创建一个py文件(run.py),用于将函数提交给celery
# 1、导入刚才编写的函数
from main import add # 2、将任务提交给broker,函数需要的参数需要传入
res = add.delay(1, 2)
# 3、提交后可以获得该任务的ID,可通过ID可以查询任务执行结果
print(res) # 0213d2c2-453e-41a8-a171-e31f1f2f4883 - 3、第三步:使用命令开启worker (也可以提前开启,任务提交后就会直接执行)
# 启动worker命令,win需要安装eventlet
# 启动需要进入main.py文件的目录下
win:
-4.x之前版本
celery worker -A main -l info -P eventlet
-4.x之后
celery -A main worker -l info -P eventlet
mac:
celery -A main worker -l info - 4、第四步:worker会将执行的结果存在之前指定的broker目录下(指定的redis数据库) - 5、第五步:通过代码查看执行结果(创建新的py文件,专门用于查看执行结果)
# 1、导入celery实例的对象
from main import app
# 2、导入该模块用于查看结果
from celery.result import AsyncResult # 3、将提交的任务编号拿过来,用于查询结果
id = '0213d2c2-453e-41a8-a171-e31f1f2f4883' # 4、指定该文件为启动文件
if __name__ == '__main__':
# 实例化对象,将任务的ID和celery实例化对象当作参数传入
a = AsyncResult(id=id, app=app)
# 判断执行结果
if a.successful(): # 执行完了
result = a.get()
print(result)
elif a.failed():
print('任务失败')
elif a.status == 'PENDING':
print('任务等待中被执行')
elif a.status == 'RETRY':
print('任务异常后正在重试')
elif a.status == 'STARTED':
print('任务已经开始被执行')

二、Celer包结构

1、创建clery包结构

什么是包结构:通过将celery服务封装成包的形式,放在项目需要使用的时候导入即可

project
├── celery_task # celery包
│ ├── __init__.py # 包文件
│ ├── celery.py # celery连接和配置相关文件,且名字必须交celery.py
│ └── tasks.py # 所有任务函数
├── add_task.py # 添加任务
└── get_result.py # 获取结果

创建包:

创建一个包,名为:celery_task

- 1、第一步:在包下创建py文件(名字必须为celery.py)
# 导入celery模块
from celery import Celery
# 导入配置broker和backend
from .settings import BACKEND, BROKER # 实例化celery对象
app = Celery('test',
broker=BROKER,
backend=BACKEND,
include=['celery_task.order_task',
'celery_task.user_task']) - 2、第二步:创建settings.py,用于存放配置
BROKER = 'redis://127.0.0.1:6379/1'
BACKEND = 'redis://127.0.0.1:6379/2' - 3、第三步,创建py文件(task.py),用于存放需要执行的异步任务
# 导入celery实例对象
from .celery import app # 计算函数
@app.task()
def add(a, b):
print('计算结果为:', a + b)
return True # 模拟发送短信
@app.task()
def send_sms(mobile, code):
print('已向手机号:%s 发送短信,验证码为:%s' % (mobile, code))
return True - 4、第四步:开启worker
切换到celery所在的目录下,开启worker命令
celery -A celery_task worker -l info -P eventlet - 5、第五步:提桥任务: # add_task.py 文件下
# 提交任务,这里模拟的是异步任务的提交
res = add.delay(a, b) # 提交后可以接收任务的ID
res1 = send_sms.delay(mobile, code) - 6、第六步:查看任务执行结果: # get_result.py 文件下
# 导入celery实例
from celery_task.celery import app
from celery.result import AsyncResult id = res
id1 = res1 # 通过传入任务的ID就可以查询到任务的执行结果
def res_func(id):
id = id
a = AsyncResult(id=id, app=app)
if a.successful(): # 执行完了
result = a.get()
if result: return '执行完成'
elif a.failed():
return '任务失败,失败的原因可能是未开启worker'
elif a.status == 'PENDING':
return '任务等待中被执行,当前任务较多或未开启worker'
elif a.status == 'RETRY':
return '任务异常后正在重试'
elif a.status == 'STARTED':
return '任务已经开始被执行,请稍后查询'

2、Celery执行异步任务、延迟任务、定时任务

执行异步任务:

# 代码用法:
函数名.delay('函数执行需要的参数')
res = func.delay(*args,**kwargs) # res 用于接收提交任务的ID

执行延迟任务:

# 代码用法:
# 1、执行延迟任务
from datetime import datetime, timedelta # 设置延迟后的时间,一分钟后执行
eat = datetime.utcnow() + timedelta(minutes=1) # 提交任务
res = send_sms.apply_async(args=['13855411111', '123'], eta=eta)

执行定时任务:

执行定时任务需要启动beat和worker

  • beat:定时提交任务的进程---》配置在app.conf.beat_schedule的任务
  • worker:执行任务
- 第一步:在celery的py文件中写入
# 导入定时需要的模块
from celery.schedules import crontab
# 第一步:在celery的py文件中写入
app.conf.timezone = 'Asia/Shanghai'
# 是否使用UTC
app.conf.enable_utc = False
# celery的配置文件#####
# 任务的定时配置
app.conf.beat_schedule = {
'send_sms': { # 配置执行函数的名字
'task': 'celery_task.task.send_sms', # 导入任务的位置
# 'schedule': timedelta(seconds=3), # 时间对象
# 'schedule': crontab(hour=8, day_of_week=1), # 每周一早八点
'schedule': crontab(hour=9, minute=43), # 每天9点43
'args': ('18888888', '6666'), # 配置执行函数需要的参数
},
} - 第二步:启动beat # 启动后配配置的任务会自动提交
celery -A celery_task beat -l info - 第三步:启动worker # beat提交的任务被被执行
celery -A celery_task worker -l info -P eventlet

三、Django中使用celery

补充:

如果在公司中,只做定时任务有一个框架更简单一点

使用步骤:

-1 把咱们写的包,复制到项目目录下
-luffy_api
-celery_task #celery的包路径
-luffy_api #源代码路径 -2 在使用提交异步任务的位置,导入使用即可
-视图函数中使用,导入任务
-任务.delay() # 提交任务 -3 启动worker,如果有定时任务,启动beat -4 等待任务被worker执行 -5 在视图函数中,查询任务执行的结果

1、模拟写一个异步秒杀任务

后端

view.py

from celery.result import AsyncResult
from celery_task.celery import app
from celery_task.task import sckill_task # 秒杀接口
class SeckillView(ViewSet): # 开启秒杀
@action(methods=['GET'], detail=False)
def seckill(self, request):
# 获取商品链接
goods_id = request.query_params.get('goods_id')
# 将任务提交给worker
res = sckill_task.delay(goods_id)
# 将任务的ID反馈给前端
return APIResponse(task_id=str(res)) # 查询秒杀结果
@action(methods=['GET'], detail=False)
def get_result(self, request):
# 前端将任务ID产过来,用于接收结果
task_id = request.query_params.get('task_id')
# 调用接口,查询结果
a = AsyncResult(id=task_id, app=app)
if a.successful():
result = a.get()
if result:
return APIResponse(msg='秒杀成功')
else:
return APIResponse(code=101, msg='手速满了,秒杀失败')
elif a.status == 'PENDING':
return APIResponse(code=666, msg='加速秒杀中')
return APIResponse(msg='错误')

celery.py ---->秒杀任务

import random

# 秒杀函数
@app.task()
def sckill_task(goods_id):
print('商品正在秒杀中')
time.sleep(random.choice([6, 7, 8, 9]))
print('商品秒杀结束')
return random.choice([True, False])

前端:

<template>
<div>
<button @click="clickHandle">点击秒杀</button>
</div>
</template> <script>
export default {
name: "Template",
data() {
return {
// 用于接收任务ID
task_id: '',
// 用户存放定时任务
t: ''
}
},
methods: {
// 用户点击秒杀后发送请求
clickHandle() {
// 向厚点提交秒杀任务
this.$axios.get(this.$settings.BASE_URL + '/user/seckill/seckill/?goods_id=1').then(res => {
// 判断任务是否提交成功
if (res.data.code == 100) {
// 提交成功会获取到任务ID
this.task_id = res.data.task_id
// 告知用户商品正在秒杀中
this.$message('正在秒杀中')
// 启动一个定时任务,每隔3秒向后端发送请求,获取任务是否提交成功
this.t = setInterval(res => {
// 定时向后端发送请求,判断秒杀结果
this.$axios.get(this.$settings.BASE_URL + '/user/seckill/get_result/?task_id=' + this.task_id).then(res => {
// 判断任务是否结束
if (res.data.code == 666) {
this.$message(res.data.msg)
// 任务结束反馈结果,关闭定时器
} else {
this.$message(res.data.msg)
// 关闭定时器
clearInterval(this.t)
this.t = ''
}
})
}, 3000)
}
})
}
}
}
</script>

2、总结

  • 第一步:将celery包复制到项目路径下
-luffy_api
-celery_task #celery的包路径
celery.py # 一定不要忘了一句话
import os
# 重点:celery中使用djagno,任务中可能会使用django的orm,缓存,表模型。。。。一定要加
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'luffy_api.settings.dev')
-luffy_api #源代码路径
  • 第二步:在需要使用异步的地方导入celery实例即可使用
-视图函数中使用,导入任务
-任务.delay() # 提交任务
  • 第三步:启动worker,如果有定时任务,启动beat

  • 第四步: 等待任务被worker执行

  • 第五步:在视图函数中,查询任务结果

Celery框架从入门到精通的更多相关文章

  1. Python必学Django框架,入门到精通学习视频教程全都在这可以领

    “人生苦短,我用python”,学python的小伙伴应该都了解这句话的含义.但是,学python,你真正了了解强大的Django框架吗!? 据说Django还是由吉普赛的一个吉他手的名字命名的呢,有 ...

  2. adminlte前端框架从入门到精通

    第一 下载 admintle的下载地址为: https://github.com/almasaeed2010/AdminLTE/releases 参考实例文件代码: 例如:AdminLTE-2.4.3 ...

  3. laravel从5.2到5.5从入门到精通视频教程共16套

    laravel从5.2到5.5从入门到精通视频教程共16套,大部分都是实战项目比如P2P.博客.短网址.知乎门户.app软件开发.微信商城实战等 课程目录: 01.Laravel框架从入门到精通02. ...

  4. Spring Boot从入门到精通(六)集成Redis实现缓存机制

    Redis(Remote Dictionary Server ),即远程字典服务,是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并提供多种语言 ...

  5. 【无私分享:从入门到精通ASP.NET MVC】从0开始,一起搭框架、做项目 目录索引

    索引 [无私分享:从入门到精通ASP.NET MVC]从0开始,一起搭框架.做项目(1)搭建MVC环境 注册区域 [无私分享:从入门到精通ASP.NET MVC]从0开始,一起搭框架.做项目(2)创建 ...

  6. 22、ASP.NET MVC入门到精通——搭建项目框架

    本系列目录:ASP.NET MVC4入门到精通系列目录汇总 前面的章节,说了ASP.NET MVC项目中常用的一些技术和知识点,更多的是理论上面的东西,接下来,我将通过一个简单的OA项目来应用我们之前 ...

  7. Spring Boot从入门到精通(九)整合Spring Data JPA应用框架

    JPA是什么? JPA全称Java Persistence API,是Sun官方提出的Java持久化规范.是JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中. ...

  8. Spring Boot从入门到精通(十一)集成Swagger框架,实现自动生成接口文档

    Swagger是一个规范和完整的框架,用于生成.描述.调用和可视化 RESTful 风格的 Web 服务.Swagger 是一组开源项目,其中主要要项目如下: Swagger-tools:提供各种与S ...

  9. ASP.NET MVC4入门到精通系列目录汇总

    序言 最近公司在招.NET程序员,我发现好多来公司面试的.NET程序员居然都没有 ASP.NET MVC项目经验,其中包括一些工作4.5年了,甚至8年10年的,许多人给我的感觉是:工作了4.5年,We ...

  10. 5、ASP.NET MVC入门到精通——NHibernate代码映射

    本系列目录:ASP.NET MVC4入门到精通系列目录汇总 上一篇NHibernate学习笔记—使用 NHibernate构建一个ASP.NET MVC应用程序 使用的是xml进行orm映射,那么这一 ...

随机推荐

  1. pandas常用方法之read_excel详解

    前期准备 准备测试数据如下: fl_path = r"C:\Users\Desktop\test.xlsx" dic = { 'num': ['001', '002', '003' ...

  2. 2022-3-17内部群每日三题-清辉PMP

    1.一个项目预算为6000万美元,预计需要24个月才能完成.12个月后,该项目完成了60%,并使用了3500美元.那么预算和进度的状态如何? A.符合预算,并超前于进度 B.超出预算,但超前于进度 C ...

  3. UGUI获取文本的字符内容像素宽度 【转】

    在做文本框的时候,我们经常碰到需要计算字符输入的长度,然后适当地做处理.这个时候不能直接了当地拿text.Length来用,原因有: 1.字符会因为fontSize的大小不同而有不同的宽度: 2.即使 ...

  4. WAP-2.1

    WAP 是一种源代码静态分析和数据挖掘工具,用于检测和纠正用 PHP 4.0 或更高版本编写的 Web 应用程序中的输入验证漏洞,且误报率较低. WAP 检测并纠正以下漏洞: SQL Injectio ...

  5. [377] Prelude Opcodez

    [377] Prelude Client 00 SendProtocolVersion 01 MoveBackwardToLocation 02 Say 03 RequestEnterWorld 04 ...

  6. VUE 一些小功能(查重、逻辑删除)

    查重就是在表中查找是否有该值,如果有返回0没有则返回1 在API写添加方法时可以直接通过该方法返回值进行添加,如果是0则添加,1则重名   不进行添加 逻辑删除就是在信息表中添加一个删除状态的字段,比 ...

  7. 【python】第一模块 步骤四 第一课、初始正则表达式

    第一课.初始正则表达式 一.课程介绍 1.1 课程概要 步骤介绍 正则表达式入门及应用 正则的进阶 案例 综合项目实战 二.正则表达式的基本操作(多敲代码多做练习) 2.1 什么是正则表达式 什么是正 ...

  8. obs问题记录

    1.安装obs后,可能无法使用,需要下载dll文件,我的阿里云盘中有: 2.录制时电脑没电会报错'编码器错误': 3.插上声卡后播放视频想听到声音需要在声卡上插耳机听: 4.

  9. pytorch杂谈

    inputs=tt.randn([10,3])可以随机生成高维度的数组 2. 定义一个模型为modle modle.cpu()将其调用到cpu modle.cuda()将其调用到gpu 3. 关于Cr ...

  10. IDEA2021 在jsp文件中 写out报错

    报错原因: 是因为没有关联好服务器: 解决方案 File --> Project structure --> Modules --> 选中当前的模板 --> Dependenc ...