简单介绍:
说明: 此模块是一个专注于分布式消息传递的异步任务队列,所谓任务就是消息,消息中的有效载荷中包含要执行的任务需要的全部数据
几大特性:
1. Celery易于使用和维护,且不需要配置文件,默认配置启动时自动写入消息代理.
2. Celery高可用,连接丢失或失败时客户端或消费者会自动重试,并且可通过消息代理的双主/主从模式来提高高可用性
3. Celery快速,单个进程每分钟可处理百万任务,且优化后可保持往返延迟在亚毫秒级别
4. Celery灵活,几乎所有部分都支持扩展或单独使用,连接池,序列化,压缩模式,日志,调度器,消费者,生产者,自动扩展,中间人传输等
5. Celery消息代理完美支持RabbitMQ和Redis,其它实验性支持,结果存储完美支持AMQP/Redis/Memcached/MongoDB/SQLAlchemy/DjangoORM/Apache Cassandra,序列化完美支持Pickle/Json/Yaml/Msgpack/Zlib/Bzip2,并发模式完美支持Prefork/Eventlet/Gevent/Worker.
常用架构:
说明: 任务生产者通过Celery API将需要执行的任务丢到一个消息代理的消息队列中,然后由任务消费者根据自身情况从消息队列中获取任务执行,可将它们执行后结果存储,任务发布者/任务消费者是分开运行从而达到异步效果,但是需要注意的是消息代理并不属于Celery组件,官方目前完全支持的有RabbitMQ和Redis,但个人强烈建议RabbitMQ.
补充: 如上Producer既可以为Celery Client也可为Publisher,这是因为Celery作为分布式消息传递的异步任务队列,应用是可以灵活的部署在单台(通过导入执行任务单元)或多台(通过app.send_task(func, (args))实现)主机上.
方案选型:
说明: 综上所属,为了提供更高的性能,强烈推荐选择RabbitMQ做消息代理,C库Librabbitmq做PY客户端接口,Msgpack做客户端与消费者消息序列化,Redis做结果存储.
快速安装:
PY2.6.X: pip install --upgrade "kombu==3.0.37" "celery[librabbitmq,redis,msgpack]==3.1.25" PY2.7.X: pip install --upgrade "kombu==3.0.37" "celery[librabbitmq,redis,msgpack]==3.1.25"
注意: 由于Celery3.1.25以上的版本由于官方缺乏资金而移除了相当多的功能,所以还是强烈推荐使用3.1.25这个跨平台长期稳定支持版,目前依然支持PY2.6.X和PY2.7.X
快速上手:
#!/usr/bin/env python # -*- coding: utf-8 -*- # @Date : 2016-12-24 16:27:01 # @Author : 李满满 ([email protected]) # @Link : http://xmdevops.blog.51cto.com/ # @Version : $Id$ from __future__ import absolute_import # 说明: 导入公共模块 from celery import Celery # 说明: 导入其它模块 app = Celery( __name__, broker=‘amqp://root:[email protected]:5672//‘, backend=‘redis://10.2.5.51:5123/0‘, include=[ ], ) @app.task def add(x, y): return x + y
说明: Celery应用必须是可导入的,PY一切皆模块,所以保存如上代码为app.py即可,简单说明,Celery类的第一个参数是当前模块名称,而且是必须的,broker指定消息代理,backend指定结果存储,include指定多个任务执行文件相对导入位置,然后在终端中执行celery worker -A app --loglevel=info启动消费者,然后再启动一个终端在PyShell中执行from app import add;
add.delay(4, 4),此时会调用任务异步返回一个AsyncResult实例,用于检查任务状态result.ready()/等待任务完成result.get(timeout=1, propagate=False)/获取任务返回值,此时可以分别在两边终端以及结果存储中查看变化,其它高端玩法可通过celery --help获取.
必知必会:
说明: 命令行执行celery worker -A <app> --loglevel=info时,<app>必须可导入,所以可以为PY模块或包,但需要注意的不管是包还是模块都必须正确指定Celery入口文件(如果为包则默认的入口文件名为celery.py)的绝对导入名称(app/work.app),Celery通过动态导入获取实例化后的应用,通过实例化时指定的配置以及include来依次导入任务执行文件中的任务指定单元,然后就是等待任务,可以看出Celery是通过相对/绝对导入来查找定义的任务执行单元,PY导入成功后会生成PYC文件,所以代码修改后一定要先删除PYC文件.