Celery入门指南:异步任务处理与分布式调度

什么是Celery

Celery 是一个基于 Python 的分布式任务队列框架,专注于实时处理异步任务和任务调度。它允许将耗时的任务从主应用程序中异步分离出来,并通过消息传递在多个进程、主机或数据中心中执行这些任务

Celery 架构

  • 消息中间件(Broker) :Celery 不提供消息服务,但支持与 RabbitMQ、Redis 等第三方消息中间件集成。这些中间件负责接收任务并将其分发给 Worker
  • 任务执行单元(Worker) :Worker 是 Celery 提供的任务执行单元,可以并发运行在分布式系统的多个节点上,从而提高任务处理效率
  • 任务结果存储(Result Backend) :用于存储 Worker 执行任务的结果,支持多种存储方式,如 Redis、RabbitMQ 等

Celery 常用场景

  • 异步任务处理:将耗时操作如发送邮件、处理图像等异步执行,以提高应用程序的响应速度
  • 定时任务:通过 Celery Beat 进行任务调度,定期执行任务
  • 分布式任务调度:支持多个 Worker 的分布式部署,实现任务的负载均衡和高可用性

如何使用 Celery

1. 安装 Celery

使用 pip 安装 Celery:

bash 复制代码
pip install celery

2. 配置 Celery

创建一个 Celery 应用实例,指定消息代理(Broker)和结果后端(Result Backend):

python 复制代码
from celery import Celery

app = Celery('my_app', broker='redis://localhost', backend='redis://localhost')

3. 定义任务

使用 @app.task 装饰器定义需要异步执行的任务:

python 复制代码
@app.task
def add(x, y):
    return x + y

4. 启动 Celery Worker

在终端中运行以下命令启动 Celery Worker:

css 复制代码
bash
celery -A my_app worker --loglevel=info

5. 触发任务

在主应用程序中触发异步任务的执行:

ini 复制代码
python
result = add.delay(5, 5)

6. 获取任务结果

使用 result.get() 方法获取任务的执行结果:

python 复制代码
print(result.get())

7. 配置文件

可以通过配置文件(如 celeryconfig.py)来设置 Celery 的参数,如序列化方式、任务过期时间等:

python 复制代码
CELERY_TASK_SERIALIZER = 'msgpack'
CELERY_RESULT_SERIALIZER = 'json'
CELERY_TASK_RESULT_EXPIRES = 60 * 60 * 24

示例案例

异步执行多个任务

python 复制代码
from proj.tasks import add
import time

t1 = time.time()

r1 = add.delay(1, 2)
r2 = add.delay(2, 4)
r3 = add.delay(3, 6)

r_list = [r1, r2, r3]

for r in r_list:
    while not r.ready():
        pass
    print(r.result)

t2 = time.time()
print('共耗时:%s' % str(t2-t1))

在这个例子中,我们异步执行了三个任务,尽管每个任务都有 1 秒的延迟,但总耗时仍然接近 1 秒,因为任务是并发执行的。

Celery Beat 任务调度

可以使用 Celery Beat 来定时执行任务。首先,需要在配置文件中定义调度任务:

python 复制代码
from celery.schedules import crontab

CELERY_BEAT_SCHEDULE = {
    'add-every-10-seconds': {
        'task': 'proj.tasks.add',
        'schedule': 10.0,  # 每10秒执行一次
        'args': (5, 5)
    },
}

然后,启动 Celery Beat 进程:

bash 复制代码
celery -A my_app beat --loglevel=info

这将使任务每 10 秒执行一次。

相关推荐
狂炫一碗大米饭14 分钟前
大厂一面,刨析题型,把握趋势🔭💯
前端·javascript·面试
JPC客栈32 分钟前
LeetCode面试经典 150 题(Java题解)
java·leetcode·面试
常年游走在bug的边缘1 小时前
基于spring boot 集成 deepseek 流式输出 的vue3使用指南
java·spring boot·后端·ai
Moment1 小时前
前端远程面试全记录:项目、思维、管理一个不落 😔😔😔
前端·javascript·面试
张力尹1 小时前
关于 MutableSharedFlow 的 tryEmit 和 emit 争议说法
android·面试·kotlin
廖广杰1 小时前
java虚拟机-为何元空间取代永久代
后端
李菠菜1 小时前
配置 MySQL 8 允许 Root 用户远程访问
后端·mysql
dleei1 小时前
扫码登录实现
前端·javascript·面试
稀土君1 小时前
🔥 万「友」引力计划上线啦,轻松做任务赢积分“拿”华为MatePad Air、雷蛇机械键盘、 热门APP会员卡...
前端·人工智能·后端
tactfulleaner1 小时前
小于n的最大数
后端