Celery
Celery 是一个强大的分布式任务队列,它可以让任务的执行完全脱离主程序,甚至可以被分配到其他主机上运行。我们通常使用它来实现异步任务和定时任务
主要包含以下几个模块
- 任务模块 Task包含异步任务和定时任务。其中,异步任务通常在业务逻辑中被触发并发往任务队列,而定时任务由 Celery Beat 进程周期性地将任务发往任务队列。
- 消息中间件 Broker,即为任务调度队列,接收任务生产者发来的消息(即任务),将任务存入队列。Celery 本身不提供队列服务,官方推荐使用 RabbitMQ 和 Redis 等。
- 任务执行单元Worker 是执行任务的处理单元,它实时监控消息队列,获取队列中调度的任务,并执行它。
- 任务结果存储 Backend 用于存储任务的执行结果,以供查询。同消息中间件一样,存储也可使用 RabbitMQ, Redis 和 MongoDB 等。
简单示例
from __future__ import absolute_import, unicode_literals from celery import Celery # 第一个参数是当前模块的名称,这个参数是必须的 # amqp://user:pwd@10.240.1.103:5672// # redis://:password@hostname:port/db_number app = Celery('tasks',backend='amqp', broker='amqp://admin@10.240.1.103//') app.conf.update( result_expires=3600, # 3600秒后过期 ) # 定义了一个单一任务,称为 add ,返回两个数字的和 @app.task def add(x, y): return x + y # 速率限制,每分钟处理60个task @app.task(rate_limit='60/m') def add(x, y): return x + y
调用任务
from tasks import add f=add.delay(4, 4) f.ready() # 查看任务执行状态,True/False f.apply_async() f.get([timeout=3]) # 获取任务执行结果 propagate=False f.result 不阻塞, f.traceback # 异常信息 f.state 任务的执行状态
定时任务
项目结构如下:
celery_demo # 项目根目录 ├── celery_app # 存放 celery 相关文件 │ ├── __init__.py │ ├── celeryconfig.py # 配置文件 │ ├── task1.py # 任务文件 1 │ └── task2.py # 任务文件 2
__init__.py
from celery import Celery app = Celery('demo') # 创建 Celery 实例 app.config_from_object('celery_app.celeryconfig') # 通过 Celery 实例加载配置模块
celeryconfig.py
BROKER_URL = 'redis://127.0.0.1:6379' # 指定 Broker CELERY_RESULT_BACKEND = 'redis://127.0.0.1:6379/0' # 指定 Backend CELERY_TIMEZONE='Asia/Shanghai' # 指定时区,默认是 UTC # CELERY_TIMEZONE='UTC' CELERY_IMPORTS = ( # 指定导入的任务模块 'celery_app.task1', 'celery_app.task2' ) CELERYBEAT_SCHEDULE = { 'add-every-30-seconds': { 'task': 'celery_app.task1.add', 'schedule': timedelta(seconds=30), # 每 30 秒执行一次 'args': (5, 8) # 任务函数参数 }, 'multiply-at-some-time': { 'task': 'celery_app.task2.multiply', 'schedule': crontab(hour=9, minute=50), # 每天早上 9 点 50 分执行一次 'args': (3, 7) # 任务函数参数 } }
task.py
task1.py import time from celery_app import app @app.task def add(x, y): time.sleep(2) return x + y task2.py import time from celery_app import app @app.task def multiply(x, y): time.sleep(2) return x * y
启动
celery -A celery_app worker --loglevel=info celery beat -A celery_app # 启动 Celery Beat 进程,定时将任务发送到 Broker celery -B -A celery_app worker --loglevel=info # 一次启动
浙公网安备 33010602011771号