Celery5.2学习&配置

手头的Django 3.2项目需要Celery,一翻百度,发现全是基于Django 2.2的帖子,再一看官方仓库和文档,妈耶,清一色英文说明。有个半吊子的中文翻译(又不是不能看.jpg),只能自己摸坑慢慢爬去了。

本篇文章全程无图,字多慎入

官方仓库地址:

https://github.com/celery/celery/

官方文档

https://docs.celeryq.dev/en/stable/

自己写的项目(后端不会长期开着,要测试本地自行踩坑自建)

https://gitee.com/mocus/todo-list

同一批写的项目,如果ta们开放权限的话应该能看到,也是用了celery的

https://gitee.com/li-jiayin167

https://gitee.com/BabyMuu/todo-api

https://github.com/YichenWu11/simple-todolist

什么是Celery

高性能异步框架,支持异步调用,需要RabbitMQ或redis作为队列支撑

我觉得这个讲的不错,这里就不过多赘述了,里面也提供了上手样例

高性能异步框架Celery入坑指南

实在不行,还可以跟着官方得初步教程走

First Steps with Celery

安装命令

1
pip install -U "celery[redis]"

踩坑

Task handler raised error: ValueError(‘not enough values to unpack (expected 3, got 0)’)

1
pip install eventlet # celery 4.0+版本以后不支持在windows运行,还需额外安装eventlet库

celery 报错 in on_task_received 解决

专门有一个刷新的坑,celery队列不能共用(比如本地调试用了redis的db1和db2,上传到服务器上的时候,服务器上还是db1和db2,这时候本地再用db1和db2就会发生一些奇怪事情,所以本地最好用db3和db4)

简单上手

Tip:”简单上手”是早些时间的笔记,要想用在Django还需要额外的配置

连接控制台

1
2
3
celery -A tasks worker --loglevel=info
celery -A task worker --loglevel=info -P eventlet
celery -A tasks control rate_limit tasks.add 10/m

任务文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from celery import Celery

app = Celery('tasks', broker='pyamqp://guest:guest@14.222.31.232//')

@app.tasks
def add(x, y):
print("input is {} {}".format(x,y))
return x + y

if __name__ == '__main__':
print('task start....')
result = add.delay(2,3)
print('task end....')
print(result)

开启任务

1
2
from task import add
add.delay(3,4)
1
2
3
4
print(result.ready())
获取运行结果
判断
result.get(timeout=1)

获取运行结果

需要设置backend

当时第一次用的是RabbitMQ,不像redis一样可以做backend,所以就没有下文了

连接redis

在settings.py里面配置

1
redis://:password@hostname:port/db_number

Django 3.2联动Celery5.2

如果没按上面的指令安装,下面这个也能实现同样效果

1
2
pip install celery
pip install redis

给Django配置计划任务需要的插件

1
pip install django-celery-beat

插件的官方说明书

Periodic Tasks

基本按照下面这个连接的方案配置,这个方案讲述过于简略,在后期配置埋了坑

django 使用 celery

结合下面这个教程才解决问题

Django项目使用Celery

单独在settings.py配置关键字CELERY_BEAT_SCHEDULER

1
CELERY_BEAT_SCHEDULER = 'django_celery_beat.schedulers:DatabaseScheduler'

别问我为什么不是其他关键字,反正其他的都没成功,还没找到原因

动态添加&修改任务

Django使用 django-celery-beat动态添加定时任务

从设置上设定初始任务

是这样写,但没成功过

1
2
3
4
5
6
7
8
9
10
CELERYBEAT_SCHEDULE = {
# 每过10秒执行以下task1.add的定时任务
'task1':{
'task': 'course-task',
'schedule': timedelta(seconds=10),
'options':{
'queue': 'beat_tasks'
}
},
}

配置后台运行

1
2
3
4
5
6
7
启动处理
celery multi start w1 -A proj -l info
有计划任务的还需要单独加一条下面的(配置好CELERY_BEAT_SCHEDULER的情况下)
celery multi start w1 -A proj beat -l info

如果没配置好,就用下面这条
celery -A todo beat -l info --scheduler django_celery_beat.schedulers:DatabaseScheduler

最正规的方式应该是配合supervisor,但是不太会

找到一篇上古文章讲multi实现的

celery源码分析:multi命令分析

Tip:最后beat其实是失效的,演示之前手动进入容器打开了定时刷新,最后

答辩也没有用上就是了

替代品

搜资料的时候发现了这个东西,号称要取代Celery,没时间评测,但貌似有中文文档

https://github.com/ydf0509/funboost

结语

时间太紧,英文文档没好好看,最后任务也就凑合着能用,也谈不上精通。做个记录,以后遇到新的坑也能溯源。

后续

2022.4.27

用能力的自己爬出去看

看来真的是天下苦Celery久矣

不得不吐槽一下 Python 的任务队列,异步支持太差了