详解python3+flask+celery+redis
Celery是什么?
Celery是个异步分布式任务队列。
通过Celery在后台跑任务并不像用线程那么的简单,但是用Celery的话,能够使应用有较好的可扩展性,因为Celery是个分布式架构。下面介绍Celery的三个核心组件。
生产者(Celery client)。生产者(Celery client)发送消息。在Flask上工作时,生产者(Celery client)在Flask应用内运行。
消费者(Celery workers)。消费者用于处理后台任务。消费者(Celery client)可以是本地的也可以是远程的。我们可以在运行Flask的server上运行一个单一的消费者(Celery workers),当业务量上涨之后再去添加更多消费者(Celery workers)。
消息传递者(message broker)。生产者(Celery client)和消费者(Celery workers)的信息的交互使用的是消息队列(message queue)。Celery支持若干方式的消息队列,其中最常用的是RabbitMQ和Redis.
话不多说上代码先。
一、基本框架结构
二、重要文件配置如下
在Flask中集成celery需要做到两点:
创建celery的实例对象的名字必须是flask应用程序app的名字,否则celery启动会失败;
celery必须能顺利加载初始化文件
1、__init__.py文件 (初始化flask与celery)
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from config import *
import pymysql
pymysql.install_as_MySQLdb()
db= SQLAlchemy()
from celery import Celery
# Celery相关配置
CELERY_RESULT_BACKEND= "redis://localhost:6379/0"
CELERY_BROKER_URL= "redis://localhost:6379/0"
def create_app(config_name):
app= Flask(__name__)
app.config.from_object(config[config_name])
config[config_name].init_app(app)
db.init_app(app)
register_blueprint(app)
return app
def make_celery(app=None):
app= app or create_app(os.getenv('FLASK_CONFIG')or 'default')
##在第一阶段的基础上 开始使用celery 任务调度,我这使用 redis 做为缓存服务器,安装配置redis 这 里不再赘述
celery= Celery(__name__,broker=CELERY_BROKER_URL,backend=CELERY_RESULT_BACKEND)
celery.conf.update(app.config)
TaskBase= celery.Task
class ContextTask(TaskBase):
abstract= True
def __call__(self,*args,**kwargs):
with app.app_context():
return TaskBase.__call__(self,*args,**kwargs)
celery.Task= ContextTask
return celery
def register_blueprint(app):
from app.mainimport main
app.register_blueprint(main)
from app.mailimport mail
app.register_blueprint(mail)
from app.testsimport tests
app.register_blueprint(tests)
2、tasks.py文件
"""
执行的任务文件
"""
from .import make_celery
celery= make_celery(app=None)
@celery.task()
def add_together(a,b):
return a + b
@celery.task()
def print_hello():
print('Hello World!')
3.config.py 项目的配置文件
import os
basedir= os.path.abspath(os.path.dirname(__file__))
class config:
SECRET_KEY= os.environ.get('SECRET_KEY')or 'this is a secret string'
SQLALCHEMY_TRACK_MODIFICATIONS= True
@staticmethod
def init_app(app):
pass
class DevelopmentConfig(config):
DEBUG= True
SQLALCHEMY_DATABASE_URI= 'mysql+pymysql://username:pwd@sqldbadress/db'
class TestingConfig(config):
TESTING= True
SQLALCHEMY_DATABASE_URI= 'mysql+pymysql://username:pwd@sqldbadress/db'
class ProductionConfig(config):
SQLALCHEMY_DATABASE_URI= 'mysql+pymysql://username:pwd@sqldbadress/db'
config= {
'development': DevelopmentConfig,
'testing': TestingConfig,
'production': ProductionConfig,
'default': DevelopmentConfig
}
4、manage.py (flask框架项目启动运行文件)
import os
from appimport create_app, db
from flask_scriptimport Manager, Shell
from flask_migrateimport Migrate, MigrateCommand
app= create_app(os.getenv('FLASK_CONFIG')or 'default')
manager= Manager(app)
migrate= Migrate(app, db)
def make_shell_context():
return dict(app=app,db=db)
manager.add_command("shell",Shell(make_context=make_shell_context))
manager.add_command('db', MigrateCommand)
if __name__== '__main__':
manager.run()
5、views.py 文件 (flask主要接口业务)
from .import main
from flaskimport Flask,request, jsonify
from app.tasksimport *
@main.route("/api/task_start",methods=['POST'])
def task_start():
result= add_together.delay(10,20)
print(result.wait())
return jsonify({"msg":"Welcome to my app!"})
6、启动项目步骤:
1)启动falsk框架:python manage.py runserver -h 127.0.0.1 -p 8090
2) 启动 Celery Worker:: celery -A app.tasks worker --loglevel=info
注意:如果flask和 celery 联合用的时候发现报了个错误:
NotImplementedError: No result backend is configured.
用的时候是这么用的:
CELERY_RESULT_BACKEND= "redis://localhost:6379/0"
CELERY_BROKER_URL= "redis://localhost:6379/0"
celery= Celery(__name__,broker=CELERY_BROKER_URL,backend=CELERY_RESULT_BACKEND)