Celery基本使用介绍
简介
Celery是Python开发的分布式异步任务调度模块。Celery 需要一个发送和接受消息的传输者。RabbitMQ 和 Redis 中间人的消息传输支持所有特性,但也提供大量其他实验性方案的支持,包括用 SQLite 进行本地开发。Celery 可以单机运行,也可以在多台机器上运行,甚至可以跨越数据中心运行。
- 任务模块
包含异步任务和定时任务。其中,异步任务通常在业务逻辑中被触发并发往任务队列,而定时任务由 Celery Beat 进程周期性地将任务发往任务队列。 - 消息中间件 Broker
Broker,即为任务调度队列,接收任务生产者发来的消息(即任务),将任务存入队列。Celery 本身不提供队列服务,官方推荐使用 RabbitMQ 和 Redis 等。 - 任务执行单元 Worker
Worker 是执行任务的处理单元,它实时监控消息队列,获取队列中调度的任务,并执行它。 - 任务结果存储 Backend
Backend 用于存储任务的执行结果,以供查询。同消息中间件一样,存储也可使用 RabbitMQ, Redis 和 MongoDB 等。
安装
pip install celery
注册任务
同一模块
test.py
from __future__ import absolute_import
from celery import Celery
app = Celery('test_app')
@app.task
def foo():
return 'hello world'
独立模块
目录结构
celery_test/
├── init.py
├── celery.py
└── test_task.pyCelery 实例必须在名为celery.py的文件初始化(查看源码find_app函数会搜索名为celery的模块)
def find_app(app, symbol_by_name=symbol_by_name, imp=import_from_cwd):
"""Find app by name."""
from .base import Celery
try:
sym = symbol_by_name(app, imp=imp)
except AttributeError:
# last part was not an attribute, but a module
sym = imp(app)
if isinstance(sym, ModuleType) and ':' not in app:
try:
found = sym.app
if isinstance(found, ModuleType):
raise AttributeError()
except AttributeError:
try:
found = sym.celery
if isinstance(found, ModuleType):
raise AttributeError()
except AttributeError:
if getattr(sym, '__path__', None):
try:
return find_app(
'{0}.celery'.format(app),
symbol_by_name=symbol_by_name, imp=imp,
)
except ImportError:
pass
for suspect in values(vars(sym)):
if isinstance(suspect, Celery):
return suspect
raise
else:
return found
else:
return found
return sym
- celery.py include中需要指定任务所在位置,否则无法注册任务
from __future__ import absolute_import
from celery import Celery
app = Celery('test_app', include=['celery_test.test_task'])
- test_task.py
from .celery import app
@app.task
def foo():
return "hello world"
- task共享(不绑定某个app)
用shared_task修饰时,不需要依赖于指定的app实例,可以被任何app实例使用
from __future__ import absolute_import
from celery import shared_task
@shared_task
def foo():
return "hello world"
创建任务
异步任务
1.执行foo.delay(),将创建一个异步任务
定时任务
使用@app.task 或者@shared_task注册任务后,可设置任务为定时执行(必须先注册任务,定时任务只是任务创建的一种形式,和foo.delay()是同层次的)
test_task.py
from __future__ import absolute_import
from celery import shared_task
@shared_task
def foo():
return "hello world"
@shared_task
def bar():
return "hi world"
1.@app.on_after_configure.connect创建定时任务
# coding: utf-8
from __future__ import absolute_import
from celery import Celery
from datetime import timedelta
from celery.schedules import crontab
app = Celery('test_app', include= ['celery_test.test_task'])
# 每5s执行一次,也可以用crontab格式执行
app.conf.beat_schedule = {
'crontab_task_1': {
'task': 'celery_test.test_task.bar',
'schedule': timedelta(seconds=5),
'args': ()
},
}
>
# 不会覆盖app.conf.beat_schedule 的任务,是增加一个新任务
# 注意调用方式foo.s()
from .test_task import foo
@app.on_after_configure.connect
def setup_periodic_tasks(sender, **kwargs):
# Executes every Monday morning at 7:30 a.m.
sender.add_periodic_task(
schedule=timedelta(seconds=5),
sig=foo.s(),
)
2.app.conf.beat_schedule创建定时任务
from __future__ import absolute_import
from celery import Celery
from datetime import timedelta
from celery.schedules import crontab
app = Celery('test_app', include= ['celery_test.test_task'])
# 每5s执行一次,也可以用crontab格式执行
app.conf.beat_schedule = {
'crontab_task_1': {
'task': 'celery_test.test_task.bar',
'schedule': timedelta(seconds=5),
'args': ()
},
}
"""
# 会覆盖之前的配置
app.conf.beat_schedule = {
'crontab_task_2': {
'task': 'celery_test.test_task.foo',
'schedule': timedelta(seconds=10),
'args': ()
},
}
"""
3.配置文件CELERYBEAT_SCHEDULE 创建定时任务
celeryconfig.py
from datetime import timedelta
CELERYBEAT_SCHEDULE = {
'crontab_task_1': {
'task': 'celery_test.test_task.bar',
'schedule': timedelta(seconds=5),
'args': ()
},
'crontab_task_2': {
'task': 'celery_test.test_task.foo',
'schedule': timedelta(seconds=5),
'args': ()
},
}
celery.py
# coding: utf-8
from __future__ import absolute_import
from celery import Celery
from datetime import timedelta
from celery.schedules import crontab
app = Celery('test_app', include= ['celery_test.test_task'])
app.config_from_object('celery_test.celeryconfig')
启动celery worker
- celery -A celery_test worker -B -l info
- B:启用定时任务
其他
- 通常使用Supervisor管理celery进程
- celery配置通常是个配置文件
- 注册的任务可在配置文件中设置队列等其他信息
- 默认broker和backend是rabbitmq