数据中台系列3:celery 安装与使用 window 篇

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

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
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值