文章目录
1、概述
celery 是一个使用 python 开发的分布式异步任务队列管理系统。
功能介绍可百度一下,这里不赘述。
Celery的架构由三部分组成,消息中间件(broker),任务执行单元(worker)和任务执行结果存储(task result store)组成。
celery 本身并不提供 broker 和 backend 功能,而是由 RabbitMQ 和 Redis 提供(backend 功能也可以由其他组件提供,比如数据库),因此要想使用 celery,就要先把 RabbitMQ 或者 Redis 安装部署好,相关内容见:
数据中台系列1:redis 安装使用之 windows 篇
数据中台系列2:rabbitMQ 安装使用之 window 篇
2、安装
pip install celery
celery 要在 window 环境下正常使用,还需要 eventlet 或者 gevnt 库的支持,因此
pip install eventlet
3、场景1:本机运行的异步任务 hello world
3-1、场景描述
a、broker、backend 都在本机,默认都采用 redis
b、本机启动 worker 服务(进程1)
c、本机主动生成任务,通过本机的 broker,由本机的 worker 消费后,结果输出到本机的 backend。
3-2、show me the code
本机运行的异步任务场景,如下建立文件:
x:\xxx\celery_tasks
│ celery_app.py
│ config.py
│
└─tasks
task1.py
其中:
# 文件名:celery_tasks.celery_app.py
from celery import Celery
app = Celery("domodo")
app.config_from_object('celery_tasks.config')
# 文件名:celery_tasks.config.py,配置文件
from datetime import timedelta
broker_url = "redis://127.0.0.1:6379/1"
result_backend = "redis://127.0.0.1:6379/2"
# task_serializer = 'json'
# result_serializer = 'json'
# accept_content = ['json']
enable_utc = True
timezone = 'Asia/Shanghai'
# 需要执行的任务
imports = ('celery_tasks.tasks.tasks1',)
# 文件名:celery_tasks.tasks.task1.py
# 定义一个 MyTask 类,根据任务的不同执行作不同的应对,这样它就能做很多事情,不只是将结果存入 backend 那么单一。
# 任务例子
from abc import ABC
from celery import Task
from celery_tasks.celery_app import app
class MyTask(Task, ABC):
"""
自定义一个类,继承自celery.Task
exc: 失败时的错误的类型;
task_id: 任务的id;
args: 任务函数的位置参数;
kwargs: 任务函数的关键字参数;
einfo: 失败时的异常详细信息;
retval: 任务成功执行的返回值;
"""
def on_failure(self, exc, task_id, args, kwargs, einfo):
"""任务失败时执行"""
def on_success(self, retval, task_id, args, kwargs):
"""任务成功时执行"""
print("任务执行成功")
def on_retry(self, exc, task_id, args, kwargs, einfo):
"""任务重试时执行"""
@app.task(base=MyTask)
def say_hello(x, y):
return print(f"hello world {x + y}")
3-3、运行
1)在命令行窗口1中,进入 xxx 目录,并执行以下命令,启动 celery,等待任务执行指令
celery -A celery_app worker -l info -P eventlet -c 10
如果正常运行,命令行窗口中会出现以下内容:
-------------- celery@xxxxxxxxxxx v5.3.1 (emerald-rush)
--- ***** -----
-- ******* ---- Windows-10-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
- *** --- * ---
- ** ---------- [config]
- ** ---------- .> app: xxxx:xxxxxxxx
- ** ---------- .> transport: redis://127.0.0.1:6379/1
- ** ---------- .> results: redis://127.0.0.1:6379/2
- *** --- * --- .> concurrency: 10 (eventlet)
-- ******* ---- .> task events: OFF (enable -E to monitor tasks in this worker)
--- ***** -----
-------------- [queues]
.> celery exchange=celery(direct) key=celery
[tasks]
. say_hello
[2023-07-25 01:28:57,898: INFO/MainProcess] Connected to redis://127.0.0.1:6379/1
[2023-07-25 01:28:57,901: INFO/MainProcess] mingle: searching for neighbors
[2023-07-25 01:28:58,915: INFO/MainProcess] mingle: all alone
[2023-07-25 01:28:58,921: INFO/MainProcess] pidbox: Connected to redis://127.0.0.1:6379/1.
[2023-07-25 01:28:58,925: INFO/MainProcess] celery@xxxxxxxxxxxxxx ready.
最后有 ready 字样,就表示 celery 服务运行正常,并等待任务运行指令。
2)在命令行窗口2中进入 python 后,执行以下命令,发出执行 say_hello 任务的指令:
>>> from tasks.tasks1 import say_hello
>>> say_hello.delay('alice')
<AsyncResult: 55999c5b-104a-4701-bfe9-a1490f9ed26c>
>>>
此时在命令行窗口1中的 celery 服务会接收到任务指令,执行并在窗口1中显示相关信息(如下),成功执行完毕后,根据 say_hello 装饰器中的参数 base设定,回调 on_success 方法,发出 “任务执行成功” 的信息。
[2023-07-25 01:44:08,907: INFO/MainProcess] Task say_hello[0081398c-c72f-401b-9c82-6d2f08241c53] received
[2023-07-25 01:44:08,907: WARNING/MainProcess] hello, alice
[2023-07-25 01:44:08,950: WARNING/MainProcess] 任务执行成功
[2023-07-25 01:44:08,950: INFO/MainProcess] Task say_hello[0081398c-c72f-401b-9c82-6d2f08241c53] succeeded in 0.045999999972991645s: None
由此,整个任务执行完毕。
4、场景2:本机运行的定时任务 hello world
相比第3点,本项希望能在指定条件下执行指定代码,或者重复执行指定代码。
以下默认使用 redis 作为 broker 和 backend,并且已经启动了 redis 服务。
4-1、场景描述
a、broker、backend 都在本机,默认都采用 redis
b、本机启动 worker 服务(进程1)
c、本机启动定时器,按定时器被动生成任务,通过本机的 broker,由本机的 worker 消费后,结果输出到本机的 backend。
4-2、show me the code
本机运行的异步任务场景,如下建立文件:
x:\xxx\celery_tasks
│ celery_app.py
│ config.py
│
└─tasks
task1.py
其中:
a、场景1的文件 celery_app.py, task1.py 没有改动。
b、场景1的文件 config.py 在末尾添加以下内容
# 文件名:celery_app.py
beat_schedule = {
'say_hello': {
'task': 'my_celery.tasks.tasks1.say_hello', # 绑定的定时任务函数
'schedule': 5, # 每隔 2 秒执行一次
# 'schedule': crontab(minute=42, hour=8, day_of_month=11, month_of_year=4), # 每年4月11号,8点42分执行
# 'schedule': crontab(minute='*/10',hour='3,17,22', day_of_week='thu,fri'), # 每隔10分钟执行一次,仅限于周六日3-4 am, 5-6 pm, and 10-11 pm
'args': ('张三',) # 要传递的参数
}
}
4-3、运行
1)在命令行窗口1中,进入 xxx 目录,并执行以下命令,启动 celery,等待任务执行指令
celery -A my_celery.celery_app worker -l info -P eventlet -c 10
如果正常运行,命令行窗口中会出现以下内容:
-------------- celery@xxxxxxxxxxx v5.3.1 (emerald-rush)
--- ***** -----
-- ******* ---- Windows-10-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
- *** --- * ---
- ** ---------- [config]
- ** ---------- .> app: xxxx:xxxxxxxx
- ** ---------- .> transport: redis://127.0.0.1:6379/1
- ** ---------- .> results: redis://127.0.0.1:6379/2
- *** --- * --- .> concurrency: 10 (eventlet)
-- ******* ---- .> task events: OFF (enable -E to monitor tasks in this worker)
--- ***** -----
-------------- [queues]
.> celery exchange=celery(direct) key=celery
[tasks]
. say_hello
[2023-07-25 01:28:57

本文详细介绍了Celery的使用,包括安装、本机异步任务和定时任务的实现,以及分布式部署的多个场景,如单消费者多生产者、多消费者部署,并涉及任务优先级和多队列管理。同时提到了使用Redis和RabbitMQ作为消息中间件,以及如何通过flower进行任务监控。
最低0.47元/天 解锁文章
1131

被折叠的 条评论
为什么被折叠?



