celery的组成
- Celery的架构由三部分组成,消息中间件(message broker),任务执行单元(worker)和任务执行结果存储(task
result store)组成。
- 消息中间件 Celery本身不提供消息服务,但是可以方便的和第三方提供的消息中间件集成。包括,RabbitMQ, Redis等等
- 任务执行单元 Worker是Celery提供的任务执行的单元,worker并发的运行在分布式的系统节点中。
- 任务结果存储 Task result store用来存储Worker执行的任务的结果,Celery支持以不同方式存储任务的结果,包括redis等
Celery的工作流程如下:
-
选择和安装消息传输代理(Broker):Celery需要一个方法来发送和接受消息,这个方法被称为消息代理(message
broker)。消息代理的作用是作为客户端(client)和工作进程(worker)之间的中间人,负责将任务从客户端发送到工作进程,并将结果返回给客户端。 -
安装Celery并创建第一个任务:在安装了消息传输代理之后,接下来需要安装Celery本身,并创建第一个任务。这个任务可以是一个简单的函数或类方法
-
启动Celery工作进程(Worker)并执行任务:启动Celery工作进程后,工作进程会监听队列中的任务,并将其处理完毕后返回结果。这样,Celery就可以异步地执行任务,不会阻塞主线程。
-
追踪任务的状态:在任务执行过程中,可以通过Celery提供的工具来追踪任务的状态,确保任务能够正确执行并返回结果。如果任务失败,Celery还提供了重试机制来确保任务能够成功完成。
-
调用任务:客户端通过Celery发送消息到队列中,消息代理接收到消息后,将其分发给工作进程进行处理。工作进程处理完任务后,将结果返回给客户端
简单异步代码演示
异步任务定义 celery_task.py
import celery
import time
import logging
# 消费者
logger = logging.getLogger("项目名字(随便写)")
backend = 'redis://127.0.0.1:6379/4'
broker = 'redis://127.0.0.1:6379/5' # 可换成rabbitmq
cel = celery.Celery('项目名字(随便写)', backend=backend, broker=broker,BROKER_CONNECTION_RETRY_ON_STARTUP=True)
# 启动 celery -A celery_task worker -l info -P eventlet #l info 日志的意思
# 异步任务 可多个
@cel.task
def send_email(name):
try:
print("Sending email to %s..." % name)
time.sleep(5)
print("Email sent to %s." % name)
return 'ok'
except Exception as e:
logger.error("Error in send_email: %s" % str(e))
@cel.task
def send_msg(name):
try:
print("Sending message to %s..." % name)
time.sleep(5)
print("Message sent to %s." % name)
return 'ok'
except Exception as e:
logger.error("Error in send_msg: %s" % str(e))
调用异步方法 produce_task.py
from celery_task import send_email, send_msg
from datetime import datetime
from datetime import timedelta
# 只有异步任务中有的才能调用delay方法
result = send_email.delay("子月")
print(result.id)
result = send_msg.delay("子月")
print(result.id)
# 方式二
ctime = datetime.now()
utc_ctime = datetime.utcfromtimestamp(ctime.timestamp())
time_delay = timedelta(seconds=10)
task_time = utc_ctime + time_delay
# 使用apply_async并设定时间 当前时间10min后执行
result = send_email.apply_async(["zuyue"], eta=task_time)
print(result.id)
from celery.result import AsyncResult
from celery_task import cel
async_result = AsyncResult(id="8adc715b-4230-4418-8ff7-b9af388e9d9f", app=cel)
if async_result.successful():
result = async_result.get()
print(result)
elif async_result.failed():
print("执行失败")
elif async_result.status == 'PENDING':
print('任务等待被执行中')
elif async_result.status == 'RETRY':
print('任务异常 正在重试')
elif async_result.status == 'STARTED':
print('任务已经开始被执行')
定时任务触发