zoukankan      html  css  js  c++  java
  • flask插件系列之flask_celery异步任务神器

    现在继续学习在集成的框架中如何使用celery.

    在Flask中使用celery

    在Flask中集成celery需要做到两点:

    1. 创建celery的实例对象的名字必须是flask应用程序app的名字,否则celery启动会失败;

    2. celery必须能顺利加载初始化文件。

    celery在flask中初始化

    由于celery进程的运行和flask进程的运行是相互独立的,但是在框架中我们希望只使用一份配置文件,这样可以简化配置的工作。

    from celery import Celery
    from flask import Flask
    
    app = Flask(__name__)
    
    def make_celery(app):
        celery = Celery(app.import_name)
        celery.conf.update(app.config)
        return celery
    
    celery = make_celery(app)
    # celery的配置文件在app的setting中;
    

    问题:上面的做法程序在初始化的时候可以完成celery的初始化,但是当使用工厂模式创建app的时候,celery的初始化变得困难;

    from celery import Celery
    from flask import Flask
    
    celery = None
    
    def make_celery(app):
        celery = Celery(app.import_name)
        celery.conf.update(app.config)
        return celery
    
    def create_app(config_name)
        app = Flask(__name__)
        config_class = config_map[config_name]
        app.config.from_object(config_class)
        # 初始化celery
        global celery
        celery = make_celery(app)
    
    
    • 问题:由于程序初始化的时候并不能创建出app对象,所以celery启动的时候必须先在tasks中导入app对象才能完成初始化,可能导致循环导入的错误;

    • 解决:引入Flask-Celery-Helper,帮助我们初始化celery对象;

    • 安装Flask-Celery-Helper

    pip install Flask-Celery-Helper
    
    • 将所有额外的需要初始化的对象独立出来在一个单独的py模块。
    # extensions.py
    from flask_celery import Celery
    # 创建celery的实例
    celery = Celery()
    
    # __init__.py
    from extensions import celery
    
    def create_app(config_name)
        app = Flask(__name__)
        config_class = config_map[config_name]
        app.config.from_object(config_class)
        # 对celery进行初始化操作,可以将celery的配置写在app的配置中
        celery.init_app(app=app)
    
    # tasks.py
    from extensions import celery
    
    @celery.task()
    def add(x,y):
        return x + y
    

    注意

    • Flask-Celery-Helper官方目前只支持到python3.4,但楼主使用py3.6也没有问题;Flask-Celery-Helper不支持celery4.X的版本,否则报错,因此需要使用celery3.x的版本;

    • 调用task方法

    # app.py
    
    from tasks import add
    @app.route("/index")
    def index():
        """一个测试的实例"""
        print(add(3+6)) # add函数也能做普通的函数使用
        add.apply_async(args=[5,7], queue='eegqueue') # 发送异步任务,指定队列
    
        return "ok!"
    
    

    启动celery

    启动celery之前需要加载flask的app的配置,因此需要创建一个app对象给celery使用。

    # run_celery.py
    import create_app
    flask_app = create_app("develop") # 创建app的同时,对celery完成了加载配置的工作
    from extensions import celery # 此时的celery对象已经在上下文中完成初始化
    
    # 找到celery实例的位置,指定worker,指定接收某个队列的消息,如果不指定则接收所有队列的消息
    celery -A run_celery.celery worker -Q eegqueue --loglevel=info
    
  • 相关阅读:
    Leetcode [654] 最大二叉树 &[105] 从前序与中序遍历序列构造二叉树 & [106] 从中序与后序遍历序列构造二叉树
    Leetcode [226] 翻转二叉树 & [116] 填充每个节点的下一个右侧节点指针 & [114] 二叉树展开为链表
    Leetcode 链表&二叉树刷题总结
    Leetcode 动态规划刷题总结
    Leetcode [1312] 让字符串成为回文串的最少插入次数 动态规划
    Leetcode [234] 回文链表 回文 链表
    动态规划之 KMP 算法详解(转)
    Leetcode [99] 恢复二叉搜索树 二叉树
    统计代码行数
    二叉树遍历(递归、非递归、mirror)转
  • 原文地址:https://www.cnblogs.com/cwp-bg/p/9259974.html
Copyright © 2011-2022 走看看