python的celery定时任务和异步任务的使用

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/chenbogger/article/details/99308404

记录一次在flask中对Celery的使用

celery是什么?

Celery 是一个由 Python 编写的简单、灵活、可靠的用来处理大量信息的分布式系统,它同时提供操作和维护分布式系统所需的工具。
说白了,它是一个分布式队列的管理工具,我们可以用 Celery 提供的接口快速实现并管理一个分布式的任务队列。

Brokers

brokers 中文意思为中间人,在这里就是指任务队列本身,Celery 扮演生产者和消费者的角色,brokers 就是生产者和消费者存放/拿取产品的地方(队列)
常见的 brokers 有 rabbitmq、redis

Workers

就是 Celery 中的工作者,类似与生产/消费模型中的消费者,其从队列中取出任务并执行

Tasks

就是我们想在队列中进行的任务咯,一般由用户、触发器或其他操作将任务入队,然后交由 workers 进行处理。

Backend

结果储存的地方,队列中的任务运行完后的结果或者状态需要被任务发送者知道,那么就需要一个地方储存这些结果

文件结构

(本文以 Celery4.3.0 为基础进行书写,Brokers使用rabbitmq)
文件结构

具体说明

main.py

from __future__ import absolute_import
import os
import sys

from celery import Celery
from celery.utils.log import get_task_logger

BASE_PARH = os.path.dirname(os.path.dirname(__file__))
# 增加日志记录 方便日志查找问题
log = get_task_logger(__name__)
sys.path.insert(0, BASE_PARH)

app = Celery("自定义任务名")
app.config_from_object("tasks.config")

# 定义的任务
capp.autodiscover_tasks(["tasks.message_task"])
  1. sys.path.insert(0, BASE_PARH) 将当前路径添加到python环境变量,如果不导入其他自定义模块内容,可以忽略
  2. capp.config_from_object(“tasks.config”) 以文件的方式配置celery
  3. autodiscover_tasks 自动搜索任务,可以接收多个路径

config.py

from celery.schedules import crontab


# rabbitmq 配置worker
BROKER_URL = 'pyamqp://用户名:密码@rabbitmq IP地址:5672/虚拟主机'
# redis 配置worker
# BROKER_URL = 'redis://密码@IP地址:6390/1'

CELERY_TIMEZONE = 'Asia/Shanghai'
CELERY_ENABLE_UTC = False
CELERYD_MAX_TASKS_PER_CHILD = 10
CELERY_IMPORTS = ("tasks",)

imports = [
    "tasks.message_task",  # 导入py文件
]

# 需要执行任务的配置
CELERYBEAT_SCHEDULE = {
    'test1': {
        # 具体需要执行的函数
        # 该函数必须要使用@app.task装饰
        'task': 'tasks.message_task.tasks.test1_run,
        # 定时时间
        # 每分钟执行一次,不能为小数
        'schedule': crontab(minute='*/1'),
        # 每小时执行一次
        # "schedule": crontab(minute=0, hour="*/1")
        # 执行的函数需要的参数
        'args': ()
    }
}
  1. CELERY_TIMEZONE 配置celery时区
  2. CELERY_ENABLE_UTC 是否启动UTC时间
  3. CELERYD_MAX_TASKS_PER_CHILD 配置worker执行多少任务后kill掉
  4. CELERY_IMPORTS 默认导入的任务文件名(最好不要改动)
  5. imports 导入定时任务
  6. test1 随意定义
  7. test1_run 任务名

tasks.py
配置自动搜索任务时文件名固定是tasks.py

import time
from tasks.main import app, log

def test11():
    time.sleep(1)
    print('test11')


def test22():
    time.sleep(2)
    print('test22')
    test11()


@app.task
def test1_run():
    test11()
    test22()


@app.task
def test33(a,b):
    print(a, b)
    time.sleep(3)
    print(a, b)
    return a+b
  1. app.task 加task装饰器即可让方法变为异步任务

调用

和task文件夹同级目录下创建测试文件test.py
test.py

from tasks.message_task import test33

def test():
	print("开始测试")
	result = test33.delay(4, 4) 
	print("调用异步任务结束")


if __name__ == "__main__":
	test()

delay 返回的是一个 AsyncResult 对象,里面存的就是一个异步的结果,当任务完成时result.ready() 为 true,然后用 result.get() 取结果即可。异步任务所需参数直接传递给delay即可

运行

启动worker

celery -A tasks.main worker -l info
  1. tasks.main 是启动celery文件,会自动搜索定义的任务
  2. worker 指定celery以worker运行
  3. -l 日志输入等级,同python日志定义相同
    备注:这里启动如果报错,需要安装eventlet
    安装方式: pip install eventlet
    启动命令: celery-A tasks.main worker -l info -P eventlet

定时任务的使用

在tasks.py中我们定义了任务test1_run,我已经在config.py中将该义为定时任务,现在可以启动测试

启动

启动定时任务首先需要启动一个调度器

celery beat -A tasks.main -l info

然后在重新开一个命令窗口, 开启worker执行任务

celery -A tasks.main worker -l info -P eventlet

至此,celery的使用你已经学会了,更多高级用发需要参考官方文档

在实际应用我们需要celery在后台运行,celery提供了以linux守护进程的方式,启动方式:

celery multi start -A tasks.main worker -l info -P eventlet --logfile=celery.log

celery 的更多配置,点击这里

猜你喜欢

转载自blog.csdn.net/chenbogger/article/details/99308404