celery使用笔记

celery使用笔记


本文的环境为:
windows7
python3.6
参考网络文章的方法,根据笔者的环境进行安装使用,其中踩过一些坑,特作记录如下,供大家参考,并对参考文章的作者表示感谢!

先上参考文章
异步任务神器 Celery 简明笔记 http://python.jobbole.com/87086/
异步任务神器 Celery 简明笔记 http://python.jobbole.com/84041/(两篇文章同名但类容不一样)
分布式队列神器 Celery http://python.jobbole.com/87238/
Windows安装并使用Celery
http://blog.csdn.net/dszgf5717/article/details/76945492
Django 使用 Celery 实现异步任务
http://python.jobbole.com/88276/?utm_source=blog.jobbole.com&utm_medium=relatedPosts
基于Django与Celery实现异步队列任务 http://python.jobbole.com/81953/
redis核心概念 http://blog.jobbole.com/112024/
Celery与RabbitMQ、Redis http://blog.csdn.net/chuan_yu_chuan/article/details/53913405
使用Celery踩过的坑 http://www.jianshu.com/p/9e422d9f1ce2(xys:其中提到了重复执行任务的问题和解决办法)

  在程序的运行过程中,我们经常会碰到一些耗时耗资源的操作,为了避免它们阻塞主程序的运行,我们经常会采用多线程或异步任务。比如,在 Web 开发中,对新用户的注册,我们通常会给他发一封激活邮件,而发邮件是个 IO 阻塞式任务,如果直接把它放到应用当中,就需要等邮件发出去之后才能进行下一步操作,此时用户只能等待再等待。更好的方式是在业务逻辑中触发一个发邮件的异步任务,而主程序可以继续往下运行。

celery基本概念

  Celery 是一个强大的分布式任务队列,它可以让任务的执行完全脱离主程序,甚至可以被分配到其他主机上运行。我们通常使用它来实现异步任务(async task)和定时任务(crontab)。它的架构组成如下图:

这里写图片描述

可以看到,Celery 主要包含以下几个模块:

  • 任务调度器 Beat:Beat进程会读取配置文件的内容,周期性地将配置中到期需要执行的任务发送给任务队列。
  • 任务模块 Task:包含异步任务和定时任务。其中,异步任务通常在业务逻辑中被触发并发往任务队列,而定时任务由 Celery Beat 进程周期性地将任务发往任务队列。
  • 消息中间件 Broker:即为任务调度队列,接收任务生产者发来的消息(即任务),将任务存入队列。Celery 本身不提供队列服务,官方推荐使用 RabbitMQ 和 Redis 等。
  • 任务执行单元 Worker :是执行任务的处理单元,它实时监控消息队列,获取队列中调度的任务,并执行它。
  • 任务结果存储 Backend :用于存储任务的执行结果,以供查询。同消息中间件一样,存储也可使用 RabbitMQ, Redis 和 MongoDB 等。
    异步任务

  • Producer:调用了Celery提供的API、函数或者装饰器而产生任务并交给任务队列处理的都是任务生产者。

Celery序列化

在客户端和消费者之间传输数据需要序列化和反序列化,Celery支持如表9.2所示的序列化方案:
这里写图片描述

celery实现异步任务的基本步骤

使用 Celery 实现异步任务主要包含三个步骤:

  • 创建一个 Celery 实例
  • 启动 Celery Worker
  • 应用程序调用异步任务

快速入门

  为了简单起见,对于 Broker 和 Backend,这里都使用 redis。在运行下面的例子之前,请确保 redis 已正确安装,并开启 redis 服务。然后需要安装redis的python客户端:

pip install redis

  当然,celery 也是要安装的。可以使用下面的命令来安装 celery 及相关依赖:

pip install celery

  安装过程中,会自动下载相关依赖包。如果离线安装则需要下载各个包。

  坑1:Unable to run tasks under Windows #4081
  笔者安装的是最新的celery4.1,但是在windows环境中,celery 可以正常连接,但不能正常执行任务。(参考网上解决办法1、https://segmentfault.com/q/1010000010560344/a-1020000010565971
2、celery 4.0不支持windows系统:OSError: [WinError 87] 参数错误
解决办法:采用较低的版本

Try to uninstall celery 4.1.0 and replace to 3.1.24

pip uninstall celery
pip install celery==3.1.24

创建 Celery 实例

将下面的代码保存为文件 tasks.py:

# -*- coding: utf-8 -*-
import time
from celery import Celery
broker = 'redis://127.0.0.1:6379'
backend = 'redis://127.0.0.1:6379/0'
app = Celery('my_task', broker=broker, backend=backend)
@app.task
def add(x, y):
    time.sleep(5)     # 模拟耗时操作
    return x + y

上面的代码做了几件事:

  • 创建了一个 Celery 实例 app,名称为 my_task;
  • 指定消息中间件用 redis,URL 为 redis://127.0.0.1:6379;
  • 指定存储用 redis,URL 为 redis://127.0.0.1:6379/0;
  • 创建了一个 Celery 任务 add,当函数被 @app.task 装饰后,就成为可被 Celery 调度的任务;

启动 Celery Worker

在当前目录,使用如下方式启动 Celery Worker:

celery worker -A tasks --loglevel=info

其中:

  • 参数 -A 指定了 Celery 实例的位置,本例是在 tasks.py 中,Celery 会自动在该文件中寻找 Celery 对象实例,当然,我们也可以自己指定,在本例,使用 -A tasks.app;
  • 参数 –loglevel 指定了日志级别,默认为 warning,也可以使用 -l info 来表示;
    在生产环境中,我们通常会使用 Supervisor 来控制 Celery Worker 进程。

启动成功后,控制台会显示如下输出:
这里写图片描述
显示“celery@xxxxx ready“即表示celery worker启动成功了。

调用任务

现在,我们可以在应用程序中使用 delay() 或 apply_async() 方法来调用任务。

打开notebook(或者在当前目录打开 Python 控制台),输入以下代码:

from tasks import add
add.delay(2, 8)

在上面,我们从 tasks.py 文件中导入了 add 任务对象,然后使用 delay() 方法将任务发送到消息中间件(Broker),Celery Worker 进程监控到该任务后,就会进行执行。
执行这段代码,我们看到结果为:
这里写图片描述
我们将窗口切换到 Worker 的启动窗口,会看到多了两条日志,如下图所示,可见add函数的计算结果为10:
这里写图片描述
这说明任务已经被调度并执行成功。

获取执行结果

另外,我们如果想获取执行后的结果,可以这样做:

>>> result = add.delay(2, 6)
>>> result.ready()   # 使用 ready() 判断任务是否执行完毕
False
>>> result.ready()
False
>>> result.ready()
True
>>> result.get()     # 使用 get() 获取任务结果
8

在上面,我们是在 Python 的环境中调用任务。事实上,我们通常在应用程序中调用任务。比如,将下面的代码保存为 client.py:

# -*- coding: utf-8 -*-
from tasks import add
# 异步任务
add.delay(2, 8)
print 'hello world'

运行命令 $ python client.py,可以看到,虽然任务函数 add 需要等待 5 秒才返回执行结果,但由于它是一个异步任务,不会阻塞当前的主程序,因此主程序会往下执行 print 语句,打印出结果

猜你喜欢

转载自blog.csdn.net/xys430381_1/article/details/78124960