python(59) celery异步任务处理

 1.celery的简介

  celery是一个基于分布式消息传输的异步任务队列,它专注于实时处理,同时也支持任务调度。它的执行单元为任务(task),利用多线程,如Eventletgevent等,它们能被并发地执行在单个或多个职程服务器(worker servers)上。任务能异步执行(后台运行)或同步执行(等待任务完成)。
  在生产系统中,celery能够一天处理上百万的任务。它的完整架构图如下:

组件介绍:

  • Producer:调用了Celery提供的API、函数或者装饰器而产生任务并交给任务队列处理的都是任务生产者。
  • Celery Beat:任务调度器,Beat进程会读取配置文件的内容,周期性地将配置中到期需要执行的任务发送给任务队列。
  • Broker:消息代理,又称消息中间件,接受任务生产者发送过来的任务消息,存进队列再按序分发给任务消费方(通常是消息队列或者数据库)。Celery目前支持RabbitMQ、Redis、MongoDB、Beanstalk、SQLAlchemy、Zookeeper等作为消息代理,但适用于生产环境的只有RabbitMQ和Redis, 官方推荐 RabbitMQ。
  • Celery Worker:执行任务的消费者,通常会在多台服务器运行多个消费者来提高执行效率。
  • Result Backend:任务处理完后保存状态信息和结果,以供查询。Celery默认已支持Redis、RabbitMQ、MongoDB、Django ORM、SQLAlchemy等方式。

在客户端和消费者之间传输数据需要序列化和反序列化。 Celery 支出的序列化方案如下所示:

celery序列化

库: pip install celery

2.开发

celery的应用开发涉及四个部分

  • celery 实例初始化

  • 任务的定义(定时和实时任务)

  • 任务worker的启动

  • 任务的调用

项目目录

实例化:

celery的实例化,主要包括执行Broker和backend的访问方式,任务模块的申明等

# app_test.py
from celery import Celery

app = Celery('demo_celery', include=['demo_celery.tasks'])
app.config_from_object('demo_celery.celeryconfig')

if __name__ == '__main__':
    app.start()
#celeryconfig.py
BROKER_URL = 'redis://localhost' # 使用Redis作为消息代理

CELERY_RESULT_BACKEND = 'redis://localhost:6379/0' # 把任务结果存在了Redis

CELERY_TASK_SERIALIZER = 'msgpack' # 任务序列化和反序列化使用msgpack方案

CELERY_RESULT_SERIALIZER = 'json' # 结果序列化方案

CELERY_TASK_RESULT_EXPIRES = 60 * 60 * 24 # 任务过期时间

CELERY_ACCEPT_CONTENT = ['json', 'msgpack'] # 指定接受的内容类型

任务定义:

#task.py
import time
from demo_celery.app_test import app

@app.task  #通过task装饰器声明celery任务
def add(x, y):
    time.sleep(1)
    return x + y

启动:

# -A wedo为应用模块
# -l为日志level
# -c 为进程数
celery -A demo_celery.app_test worker -l info -P eventlet

# 后台启动
nohup celery -A demo_celery.app_test worker -l info -P eventlet > ./log.log  2>&1

任务调用:

from demo_celery.tasks import add
import time

t1 = time.time()

r1 = add.delay(1, 2)
r2 = add.delay(2, 4)
r3 = add.delay(3, 6)
r4 = add.delay(4, 8)
r5 = add.delay(5, 10)

r_list = [r1, r2, r3, r4, r5]
for r in r_list:
    while not r.ready():
        pass
    print(r.result)

3.分布式

将同样的代码部署在不同的机器上,使用相同的启动命令就可以



4.redis中存放的结果

#tasks代码

import time
from demo_celery.app_test import app

@app.task
def add(x, y):
    time.sleep(1)
    return x + y

#调用代码

调用方法:

1. delay()

delay是apply_async的封装,apply_async可以支持更多的任务调用配置

2.apply_async()

eta:  调用定时任务的参数

from demo_celery.tasks import add
import time

t1 = time.time()

r1 = add.delay(1, 2)
r2 = add.delay(2, 4)
r3 = add.delay(3, 6)
r4 = add.delay(4, 8)
r5 = add.delay(5, 10)

#调用后redis中存放有对应的记录

5.定时任务、延时任务、周期任务

定时任务-调用方法中传入时间即可

time_loc = datetime(2024,3,30,11,40,59)
time_user_define = datetime.utcfromtimestamp(time_loc.timestamp())
r6 = demo_0.apply_async(args=('测试定时任务',),eta=time_user_define)

延时任务(在当前时间上加自己需要的延时,同定人任务一样调用)

周期性任务

celeryconfig.py中增加周期任务配置

# 周期性任务配置
CELERYBEAT_SCHEDULE = {
    "task1": {
        "task": "demo_celery.schedule_task.func_0",  #执行的函数
        "schedule": crontab(minute="*/1"),   # every minute 每分钟执行
        "args": ('测试周期任务0',)  # # 任务函数参数
    },

    "task2": {
        "task": "demo_celery.schedule_task.func_1",
        "schedule": crontab(minute=0, hour="*/1"),   # every minute 每小时执行
        "args": ('测试周期任务1',)
    },

}

周期任务启动命令

在启动常规celery进程前,需要启动周期任务命令

celery -A  demo_celery.app_test  beat

6.指定队列调度,队列优先级

队列与路由配置

# 配置 queue 队列
CELERY_QUEUES = (
    Queue('default', routing_key='default'),
    Queue('queue_item', routing_key='apps.item.tasks'),
    Queue('queue_daily', routing_key='apps.daily.tasks'),
)

# 配置每一个Task的Router
CELERY_ROUTES = {
    'apps.item.tasks.event_list': {
        'queue': 'queue_item',
        'routing_key': 'apps.item.tasks',
    },
    'apps.item.tasks.actual_personday': {
        'queue': 'queue_item',
        'routing_key': 'apps.item.tasks',
    },
    'apps.item.tasks.reset_progress': {
        'queue': 'queue_item',
        'routing_key': 'apps.item.tasks',
    },
    'apps.daily.tasks.repeat_rate': {
        'queue': 'queue_daily',
        'routing_key': 'apps.daily.tasks',
    },
}

启动命令

通过在不同机器上指定不同的队列启动 可以达到指定任务到指定执行机行执行

celery -A projectName worker -E -l info -n worker_daily -Q queue_daily
celery -A projectName worker -E -l info -n worker_item -Q queue_item

队列优先级

CELERY_QUEUES = (
    Queue('default', routing_key='default'),
    Queue('queue_item', routing_key='apps.item.tasks',),
    queue_arguments={'x-max-priority': 10}
)

指定优先级调度

taskA.delay(queue='queue_item',priority=5)
taskB.delay(queue='queue_item',priority=10)

Celery进阶,多队列,Flower监控, Supervistor进程管理_celery-flower的登录密码在哪里设置-CSDN博客

 

7.进程管理 -- supervisor

推荐使用进程管理工具supervisor管理celery进程,保证服务的可靠性

8.报错解决:

(已解决)ImportError: cannot import name ‘ParamSpec‘ from ‘typing_extensions‘_cannot import name 'paramspec' from 'typing_extens-CSDN博客

 Celery ValueError: not enough values to unpack (expected 3, got 0)-CSDN博客

9.参考:

任务队列神器:Celery 入门到进阶指南-腾讯云开发者社区-腾讯云

一文读懂 Python 分布式任务队列 celery (qq.com)

Celery 简介 — Celery 3.1.7 文档 (jinkan.org)

简介 - Celery 中文手册 (celerycn.io)

Celery笔记一之celery介绍、启动和运行结果跟踪 - 知乎 (zhihu.com)

Python之celery的简介与使用 - 山阴少年 - 博客园 (cnblogs.com)

使用Celery - 知乎 (zhihu.com)

异步神器celery - 简书 (jianshu.com)

  • 17
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Celery是一个Python的分布式任务队列,可以处理大量的异步任务。它可以轻松地将任务分配给多个工作进程,并在完成后将结果返回到调用方。 以下是使用Celery处理异步任务的步骤: 1. 安装Celery 可以使用pip命令安装Celery: ```python pip install celery ``` 2. 创建Celery实例 在项目中创建一个Celery实例,可以使用以下代码: ```python from celery import Celery app = Celery('tasks', broker='pyamqp://guest@localhost//') ``` 该代码创建了一个名为“tasks”的Celery实例,使用“pyamqp://guest@localhost//”作为代理。 3. 定义任务 定义一个需要异步执行的任务,例如: ```python @app.task def add(x, y): return x + y ``` 该代码定义了一个名为“add”的任务,接受两个参数x和y,并返回它们的和。 4. 启动工作进程 使用以下命令启动工作进程: ```python celery -A tasks worker --loglevel=info ``` 该命令将启动一个名为“tasks”的Celery应用程序,并使用默认的代理。 5. 调用任务 现在可以调用“add”任务,例如: ```python result = add.delay(4, 4) ``` 该代码将启动一个异步任务,将参数4和4传递给“add”任务,并返回一个AsyncResult对象。 6. 获取任务结果 可以使用以下代码获取任务结果: ```python result = add.delay(4, 4) result.wait() ``` 该代码将等待异步任务完成,并返回任务结果。 以上就是使用Celery处理异步任务的基本步骤。使用Celery还有其他高级功能,例如定时任务任务重试、任务结果存储等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值