Celery
Celery
1.介绍
Celery一个python的框架,是一个简单、灵活且可靠的,处理大量消息的分布式系统,专注于实时处理的异步任务队列,同时也支持任务调度。
Celery的架构由三部分组成:
消息中间件(message broker),通俗理解就是工会的任务墙
任务执行单元(worker),通俗理解就是冒险家来执行任务,独立执行
任务执行结果存储(backend)组成,通俗理解就是执行任务的结果
Celery没有自己的中间件,要借助于第三方提供的消息中间件,包括,RabbitMQ, Redis等等
也没有自己的存储介质,可以借助于Redis,Mysql等等
2.功能
- 异步任务:解决耗时任务
- 定时任务:解决延迟任务
- 延迟任务:解决周期(周期)任务
注意:Celery 启动起来是一个服务,如果和django一起
3.简单使用,使用异步
1.安装
直接安装
pip install celery
注意,官方说了不支持windows
还要装一个第三方模块
pip install eventlet
2.新建一个文件夹,新建一个main.py文件 这个名字随意的
from celery import Celery
# 提交的异步任务,放在里面
broker = 'redis://127.0.0.1:6379/2'
# 执行完的结果,放在这里
backend = 'redis://127.0.0.1:6379/3'
a = Celery('name', broker=broker, backend=backend) #实例化对象
@a.task # 装饰器修饰
def add(a,b):
import time
time.sleep(3)
print(a+b)
return a+b
3.另外建立一个Py文件,其实就是相当于其他程序来提交任务,而不是在celery页面中自己提交任务
from main import add
res = add.delay(10,11)
print(res)
>>> 执行后得到一串ID,这个就是任务的ID号,此时,任务还没有执行,只是提交到了消息中间件存着,可以自己打开redis的库看看
4.启动worker
要去命令行启动(开启后就一直会挂着运行了)
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
worker执行后,结果存放在backend配置的库中,这里就是放在了redis的库中
5.只要来了任务,worker就执行,执行后存放结果
6.查看结果
新建一个py文件,指定要查询的任务id号,指定要查询的celery对象
from main import a # 导入celery对象
from celery.result import AsyncResult
id = '5388bf11-f7b1-41da-a33d-b8aff016f73d'
if __name__ == '__main__':
b = AsyncResult(id=id,app=a)
if b.successful():
result = b.get()
print(result)
elif b.failed():
print('mission failed')
elif b.status == 'PENDING':
print('任务等待被执行')
elif b.status == 'RETRY':
print('任务正在重新尝试')
elif b.status == 'STARTED':
print('任务已经开始执行,但是还没有结束')
4.包结构使用
任务不应该写在celery对象产生文件中,应该分开来
1.建立一个包,名字随意
2.包中建立一个py文件,名字必须是celery,用来生成celery对象,但是多了一个参数,用来注册任务
from celery import Celery
broker = 'redis://127.0.0.1:6379/3'
backend = 'redis://127.0.0.1:6379/4'
# 注册一下任务
a = Celery('test',broker=broker,backend=backend,include=['celery_one.user_task','celery_one.order_task']) #实例化一个对象出来
3.包中建立任务py文件
from .celery import a
import time
@a.task
def send_sms(phone, code):
print(f'给{phone}发了短信,短信内容是:您本次验证码为{code},将在五分钟内有效')
time.sleep(3)
return True
4.建立添加任务的py文件,不要建立在包中,意思就是其他程序提交任务
from celery_one.user_task import send_sms
# res = send_sms('17688888888','6666')
#
# print(res)
res = send_sms.delay('17688888888','6666')
print(res)
5.命令行启动worker
一定要去到包所在的目录下,不要进入包,执行,A后面跟的就是包名
celery -A celery_one worker -l info -P eventlet
6.建立取得结果的Py文件
from celery_one.celery import a # 导入celery对象
from celery.result import AsyncResult
id = '1c869c76-d515-4872-99d6-858674cf6174' #拿着ID号去要结果
if __name__ == '__main__':
b = AsyncResult(id=id,app=a)
if b.successful():
result = b.get()
print(result)
elif b.failed():
print('mission failed')
elif b.status == 'PENDING':
print('任务等待被执行')
elif b.status == 'RETRY':
print('任务正在重新尝试')
elif b.status == 'STARTED':
print('任务已经开始执行,但是还没有结束')
5.延迟任务
这个用的很少,就是提交任务后,worker延缓一些时间再执行
django默认使用世界标准时,如果要改我们中国东八区,要去改一下
from datetime import datetime,timedelta
time = datetime.utcnow() + timedelta(seconds=10) # 要进行时间的运算,需要使用timedelta
res = send_sms.apply_async(args=['17678985653','8888'],eta=time)
print(res)
>>>worker收到了隔10秒才会执行
6.定时任务
定时提交任务是由另外一个程序来提交,相当于中间人,这个东西的配置在celery中写,这个程序叫做beat
1.在celery的py文件中写入,改时区
app.conf.timezone = 'Asia/Shanghai'
app.conf.enable_utc = False
2.beat的配置
app.conf.beat_schedule = {
'send_sms': {
'task': 'celery_one.user_task.send_sms',
# 'schedule': timedelta(seconds=3), # 时间对象
# 'schedule': cro ntab(hour=8, day_of_week=1), # 每周一早八点
#crontab 需要导入,from celery.schedules import crontab
'schedule': crontab(hour=9, minute=43), # 每天9点43
'args': ('18888888', '6666'),
},
}
3.命令行,开启beat
我这里直接用os.system一并开启了
import os
os.system('celery -A celery_one beat -l info')
4.这样beat这个进程就会按照配置来提交任务,而worker只要接到了就执行(因为对于worker而言不是延迟任务)
7.django中使用celery
-1 把咱们写的包,复制到项目目录下
-luffy_api
-celery_task #celery的包路径
celery.py # 一定不要忘了一句话给celery中
import os
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'luffy_api.settings.dev')
-luffy_api #源代码路径
-2 在使用提交异步任务的位置,导入使用即可
-视图函数中使用,导入任务
-任务.delay() # 提交任务
-3 启动worker,如果有定时任务,启动beat
-4 等待任务被worker执行
-5 在视图函数中,查询任务执行的结果
# 重点:celery中使用djagno,有时候,任务中会使用django的orm,缓存,表模型。。。。一定要加
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'luffy_api.settings.dev')
一个秒杀页面
整理一下
注意
1.当我们在某个文件执行命令时,这个文件的上一层的路径会被自动加入到环境变量中去
import sys
def add(a,b):
return a+b
print(add(1,2))
print(sys.path) # 会发现这一个文件的上一级在环境变量的第一位
2.提交任务后返回的是一个对象,虽然直接打印就是id,但是如果不是打印的时候,要点出来才是id的值
3.axios.xx().then(状态码200走这个).catch(状态码不是200走这个)
补充
1.如果在公司中,只是做定时任务,还有一个更简单的框架
APSchedule:https://blog.csdn.net/qq_41341757/article/details/118759836
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现