Celery的架构由三部分组成,消息中间件(message broker),任务执行单元(worker)和任务执行结果存储(task result store)组成。
Celery本身不提供消息服务,但是可以方便的和第三方提供的消息中间件集成。包括,RabbitMQ, Redis, MongoDB (experimental), Amazon SQS (experimental),CouchDB (experimental), SQLAlchemy (experimental),Django ORM (experimental), IronMQ
Worker是Celery提供的任务执行的单元,worker并发的运行在分布式的系统节点中。
Task result store用来存储Worker执行的任务的结果,Celery支持以不同方式存储任务的结果,包括AMQP, Redis,memcached, MongoDB,SQLAlchemy, Django ORM,Apache Cassandra, IronCache
celery和flask框架结合,实现flask网络框架中定时任务。建议各依赖模块使用virtualenv在虚拟环境下安装。
第一步是配置消息中间件
本人使用redis,redis是一个开源的、内存存储d额数据结构服务器,可用作数据库、高速缓存和消息队列代理,此处取其消息队列代理和数据库功能。 python配置:
CELERY_BROKER_URL = 'redis://localhost:6379/0'
CELERY_RESULT_BACKEND = 'redis://localhost:6379/0'
redis的安装使用可参考https://redis.io/,需要注意的原版redis由于效率问题不支持windows操作系统,微软开放技术小组(Microsoft Open Tech group)开发和维护64位windows的版本,地址https://github.com/MSOpenTech/redis,使用vs2013工程组织代码。
代码示例
from flask import Flask, render_template, jsonify
from celery import Celery
import time
demo = Flask("demo")
demo.config.from_object('config')
celery = Celery("demo", broker=demo.config['CELERY_BROKER_URL'])
celery.conf.update(demo.config)
...
if __name__ == '__main__':
demo.debug=True
demo.run(port=5000)
第二步是配置任务执行单元,由celery的worker模块实现。
第三步配置任务结果存储工具,redis的数据库功能可实现。
配置好以上三个步骤之后,即可启动celery模块和flask应用
启动celery模块:
$(venv) celery worker -A you_app -l info
单独启动flask应用:
$(venv) python app.py
完整示例
# -*- coding: utf-8 -*-
activate_this = './venv/Scripts/activate_this.py'
execfile(activate_this, dict(__file__=activate_this))
import sys
sys.path.insert(0, '../demo')
sys.stdout = sys.stderr
from flask import Flask, render_template, jsonify
from celery import Celery
import time
demo = Flask("demo")
demo.config['CELERY_BROKER_URL'] = 'redis://localhost:6379/0'
demo.config['CELERY_RESULT_BACKEND'] = 'redis://localhost:6379/0'
celery = Celery("demo", broker=demo.config['CELERY_BROKER_URL'])
celery.conf.update(demo.config)
@demo.route('/', methods=['GET'])
@demo.route('/index', methods=['GET', 'POST'])
def index():
return render_template('index.html')
@celery.task(bind=True)
def long_task(self):
while True:
print("sleep")
time.sleep(15)
return True
@demo.route('/longtask', methods=['GET', 'POST'])
def longtask():
long_task.apply_async()
return jsonify({}),200
import gevent.pywsgi
if __name__ == '__main__':
gevent_server = gevent.pywsgi.WSGIServer(('', 8082), demo)
gevent_server.serve_forever()
启动celery时,工作文件夹必须要在you_app.py文件所在文件夹,否则会提示找不到you_app模块,另外在创建flask应用时也要使用
you_app=Flask(__name__)
否则会有
AttributeError: 'Flask' object has no attribute 'user_options'
的错误。