celery服务
celery服务
官方
Celery 官网:http://www.celeryproject.org/
Celery 官方文档英文版:http://docs.celeryproject.org/en/latest/index.html
Celery 官方文档中文版:http://docs.jinkan.org/docs/celery/
celery简介
Celery异步任务框架
"""
1)可以不依赖任何服务器,通过自身命令,启动服务(内部支持socket)
2)celery服务为为其他项目服务提供异步解决任务需求的
注:会有两个服务同时运行,一个是项目服务,一个是celery服务,项目服务将需要异步处理的任务交给celery服务,celery就会在需要时异步完成项目的需求
人是一个独立运行的服务 | 医院也是一个独立运行的服务
正常情况下,人可以完成所有健康情况的动作,不需要医院的参与;但当人生病时,就会被医院接收,解决人生病问题
人生病的处理方案交给医院来解决,所有人不生病时,医院独立运行,人生病时,医院就来解决人生病的需求
"""
Celery架构
Celery的架构由三部分组成,消息中间件(message broker)、任务执行单元(worker)和 任务执行结果存储(task result store)组成。
-
消息中间件
Celery本身不提供消息服务,但是可以方便的和第三方提供的消息中间件集成。包括,RabbitMQ, Redis等等
-
任务执行单元
Worker是Celery提供的任务执行的单元,worker并发的运行在分布式的系统节点中。
-
任务结果存储
Task result store用来存储Worker执行的任务的结果,Celery支持以不同方式存储任务的结果,包括AMQP, redis等
使用场景
- 异步执行:解决耗时任务
- 延迟执行:解决延迟任务
- 定时执行:解决周期(周期)任务
celery安装配置
pip install celery
celery基本配置方法
消息中间件推荐使用缓存数据库:RabbitMQ/Redis
"""1.配置Celery对象作为app"""
import celery
broker = 'redis://127.0.0.1:6379/1' # 使用redis的db1存储
backend = 'redis://127.0.0.1:6379/2' # 使用redis的db2存储
app=Celery('任务名', broker=broker, backend=backend)
# broker存储任务代码(缓存数据库的某一个db)
# backend存储执行结果
"""2.app.task可以装饰在函数上以注册任务"""
@app.task # 让任务被注册到app中,有delay方法等
def task(*params):
执行过程
return 结果
"""3.启动worker执行单位,监听这些被注册的任务"""
win中还需要安装eventlet模块:
-4.x之前版本
celery worker -A main -l info -P eventlet
-4.x之后
celery -A main worker -l info -P eventlet
-A 后跟app产生的py文件名
-l 日志等级设置
-P eventlet (win的要求)
## 执行这条语句后,app配置的broker数据库就存入了注册的函数程序
"""4.在某处调用task时,使用delay进行提交,则提交由worker执行,
并将执行的状态或结果存放在app注册的backend数据库中"""
task(*params) # 正常调用,则为同步调用
task.delay(*params) # 使用delay调用,则提交任务到broker数据库(还未正式执行)
# 返回一个AsyncResult对象,打印的话显示其id属性
"""5.查看执行结果,可以直接通过delay返回的AsyncResult对象
也可以通过该对象的id值,重新实例化一个AsyncResult对象去查看"""
from main import app
from celery.result import AsyncResult
task_id = '51611be7-4914-4bd2-992d-749008e9c1a6' # 调用
if __name__ == '__main__':
a = AsyncResult(id=task_id, app=app)
a.successful() # 执行成功与否
a.get() # 如果执行成功,执行的结果
a.failed() # 执行失败与否
a.status # 执行的状态,有PENDING,RETRY,STARTED,SUCCESS等状态
包配置celery
以上基本配置是将Celery对象产生在一个py模块文件中的,所以启动worker的命令是:
celery -A 模块名 worker -l 日志等级 -P eventlet
而如果按照以下包结构配置,则要按包名启worker
celery -A 包名 worker -l 日志等级 -P eventlet
-包名如:celery_task
- __init__.py
- celery.py # 必须命名为celery作为Celery对象文件(利用反射)
Celery(broker=broker, backend=backend, include=[
'celery_task.order_task', # 相对于包所在的文件夹即worker起始环境
'celery_task.user_task', # 会将task文件中所有加装app.task的函数注册
'celery_task.utils_task', # 底层通过反射解决了定义顺序冲突
'out_tasks'
])
- order_task.py # 不同的task文件可以定义一些不同的异步任务
- user_task.py
from .celery import app
@app.task
def yyy():...
- utils_task.py
- ...
- out_tasks.py # 包外的任务也可以被注册
from celery_task.celery import app
@app.task
def xxx():...
ps:包外的函数可以被注册为异步任务,意味着我们想将一个函数添加成异步任务时,不必调整目录结构,只要加装app.task装饰器和在celery的app中注册即可
调用异步任务和获取执行结果
即时提交任务
asy = func.delay(func所需参数)
# asy为AsyncResult的对象,对象的独有属性只有id号,其他都是获取结果的方法
延时提交任务
eta指定任务提交的时间
asy = func.apply_async(args=[func所需参数],eta=datetime对象)
# 关于设定datetime对象的时间,可以通过timedelta进行计算,
# 也可以datetime.strptime(cls, date_string, format)根据字符串时间生成
配置定时任务
定时任务需要一个一直提交任务的进程,这个我们可以通过py文件自己写循环简单的实现,但是我们可以通过celery的beat命令按照更丰富的方式设置定时任务和提交任务。
如下在app中配置:
## celery文件
app = Celery(...) # 产生了app后
# 1.设置时区为东八区
app.conf.timezone="Asia/Shanghai"
app.conf.enable_utc = False # 取消使用utc时间
# 2.配置beat_schedule
app.conf.beat_schedule = {
'任务名称': {
'task': 'celery_task.user_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'), # 任务所需的参数
'kwargs':{} # 还可以传关键字参数
'relative':True # 时间会基于最近的时分秒去执行
},
}
ps:尝试去官网找到让定时任务失效的方法,配置options:{expires:未来的datetime},但是失败了。
启动worker和beat:
celery -A celery_task worker -l info -P eventlet # 启动worker监听任务
celery -A celery_task beat -l info # 开启beat定时启动任务
AsyncResult对象
这是任务提交方法delay等给我们的返回值,实际上,它主要是包含了很多的获取结果的方法,而对象特有的属性足够的简单,只有id值。
- id:数据属性,内存中结果的键
- get():获取数据的执行结果,如果执行失败则不能使用
- successful():成功返回true
- failed():成功返回false
- status:返回目前任务的执行执行状态
django中使用celery
如果我们想将使用了django模块和一些配置的方法设置为celery的异步任务,那么会遇到这么一个问题:worker的工作环境与django是相互独立的,所以在提交任务时,会遇到缺失配置的各种问题,此时只需要在celery.py中配置django环境即可,因为celery是worker的启动文件。
## celery.py
import os
import celery
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'luffy_api.settings.dev')
app = Celery(...)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下