[ tool ] celery 任务结构和参数配置方式

2,453 阅读3分钟

这是我参与8月更文挑战的第26天,活动详情查看: 8月更文挑战

微信公众号搜索 程序媛小庄 人生苦短 一起学Python

celery任务结构

写在一个py文件中(不推荐使用)

# worker文件
from celery import Celery
broker='redis://127.0.0.1:6379/1'  # broker任务队列
backend='redis://127.0.0.1:6379/2' # 结果存储
app=Celery(__name__,broker=broker,backend=backend)

#添加任务(使用这个装饰器装饰,@app.task)
@app.task
def add(x,y):
    print(x,y)
    return x+y
启动worker:
    需要将路径切换到该py文件的路径下,用终端执行
    - 非windows:celery worker -A celery_task -l info
    - windows:celery worker -A celery_task -l info -P eventlet
        
# 提交任务到broker文件
from celery_task import add
add(3,4)  # 直接执行,不会被添加到broker中
ret = add.delay(1,2)  # 向broker中添加一个任务
print(ret)  # ret是任务编号,后期需要通过任务编号获取任务执行结果

# 查看任务执行结果文件
from celery_task import app
from celery.result import AsyncResult
id = '3e397fd7-e0c1-4c5c-999c-2655a96793bb'
if __name__ == '__main__':
    async = AsyncResult(id=id, app=app)
    if async.successful():
        result = async.get()
        print(result)
    elif async.failed():
        print('任务失败')
        elif async.status == 'PENDING':
        print('任务等待中被执行')
    elif async.status == 'RETRY':
        print('任务异常后正在重试')
    elif async.status == 'STARTED':
        print('任务已经开始被执行')

包结构

新建一个包,包名随意,比如celery_task

image-20200818200659461

  • __init__.py/celery.py
from celery import Celery
broker='redis://127.0.0.1:6379/0'  # broker任务队列
backend='redis://127.0.0.1:6379/1' # 结果存储

app=Celery(__name__,broker=broker,backend=backend,include=['celery_task.task1',])  # 实例化Celery得到app对象

app=Celery() # 在配置文件中配置broker backend后,就可以直接实例化对象,无需传参数

app.config_from_object('celery_task.celery_config') # 如果创建了配置文件,需要加载配置文件,当配置文件中的配置与当前文件的配置产生冲突优先使用当前文件中的配置(局部优先)
  • celery_config.py

实例化app对象的配置、celery运行过程中的相关配置都可以写在该文件中

from datetime import timedelta

# 实例化app对象时的配置
BROKER_URL = 'redis://127.0.0.1:6379/2'  # broker任务队列
CELERY_RESULT_BACKEND = 'redis://127.0.0.1:6379/3'  # 结果存放地址

CELERYD_CONCURRENCY = 2 # celery worker的并发数 也是命令行-c指定的数目,事实上实践发现并不是worker也多越好,保证任务不堆积,加上一定新增任务的预留就可以
CELERYD_MAX_TASKS_PER_CHILD = 5  # 每个worker执行了多少任务就会死掉,解决celery内存泄漏

# 任务导入
CELERY_IMPORTS = (
    'celery_task.task01',
)


CELERY_TIMEZONE = 'Asia/Shanghai'
CELERY_ENABLE_UTC = False
# 定时任务,定时任务可以写在__init__.py/celery.py中,也可以写在配置文件中
CELERYBEAT_SCHEDULE = {
    'delta_task':{
        'task':'celery_task.task01.add',
        'schedule':timedelta(seconds=5),
        'args':((1,2))
    }
}
  • task.py
from .celery import app

@app.task
def add(x,y):
    print(x,y)
    return x+y
  • add_task.py
from celery_task.task01 import add

ret = add.delay(1,2)

celery参数的配置方式

  • 通过 app.conf.参数 配置

配置一些常用的参数,有一些参数无法使用该方式进行配置时还是需要使用配置文件进行配置

app.conf.timezone = 'Asia/Shanghai'
  • 直接在配置文件中配置,在__init__.py/celery.py中通过app.config_from_object('celery_task.celery_config')加载配置

通用的配置方式,实例化app对象的配置、celery运行过程中的相关配置都可以写在该文件中

# celery_config.py
CELERY_TIMEZONE = 'Asia/Shanghai'

# __init__.py/celery.py
app.config_from_object('celery_task.celery_config')
# 'celery_task.celery_config' == from celery_task import celery_config

补充

启动woker的两种方式

  • 通过命令行

celery worker -A celery_task -l info -P eventlet

  • 通过app.start(),直接右键运行
app.start(argv=['celery', 'worker', '-A', 'celery_task','-l','info', '-P', 'eventlet'])

结语

文章首发于微信公众号程序媛小庄,同步于掘金

码字不易,转载请说明出处,走过路过的小伙伴们伸出可爱的小指头点个赞再走吧(╹▽╹)