Celery分布式异步框架介绍

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.py

  • Celery 实例必须在名为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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值