flask应用celery(and factory)

    Celery( 芹菜 ) 是一个异步任务队列 /基于分布式消息传递的作业队列。它侧重于实时操作,但对调度支持也很好。 Celery 用于生产系统每天处理数以百万计的任务。 Celery 是用 Python编写的,但该协议可以在任何语言实现。它也可 以与其他语言通过 webhooks 实现。 Celery 建议的消息队列是 RabbitMQ ,但提供有限支持Redis, Beanstalk, MongoDB, CouchDB, 和数据库(使用 QLAlchemy 的或 Django ORM ) 。 Celery 是易于集成Django, Pylons and Flask ,使用 django-celery, celery-pylons and Flask-Celery 附加包即可。

 Celery 介绍

Celery 中几个基本的概念,需要先了解下,不然不知道为什么要安装下面的东西。概念: Broker Backend
什么是 broker
broker 是一个消息传输的中间件,可以理解为一个邮箱。每当应用程序调用 celery 的异步任务的时候,会向 broker传 递消息,而后 celery worker将会取到消息,进行对于的程序执行。好吧,这个邮箱可以看成是一个消息队列。其中 Broker 的中文意思是 经纪人 ,其实就是一开始说的 消息队列 ,用来发送和接受消息。这个 Broker有几个方案可供 选择: RabbitMQ ( 消息队列 ) Redis (缓存数据库), 数据库 (不推荐),等等
什么是 backend
通常程序发送的消息,发完就完了,可能都不知道对方时候接受了。为此, celery 实现了一个 backend,用于存储这 些消息以及 celery 执行的一些消息和结果。 Backend 是在 Celery 的配置中的一个配置项 CELERY_RESULT_BACKEND ,作用是保存结果和状态,如果你需要跟踪任务的状态,那么需要设置这一项,可以是 Database backend,也可以 是 Cache backend ,具体可以参考这里: CELERY_RESULT_BACKEND
对于 brokers ,官方推荐是 rabbitmq redis ,至于 backend ,就是数据库。为了简单可以都使用 redis。

celery的使用

使用 celery 包含三个方面: 1. 定义任务函数。 2. 运行 celery 服务。 3. 客户应用程序的调用。
创建一个文件 tasks.py 输入下列代码:
from flask import Flask
from celery import Celery

app = Flask(__name__)
app.config['CELERY_BROKER_URL'] = 'redis://localhost:6379/0'
app.config['CELERY_RESULT_BACKEND'] = 'redis://localhost:6379/0'

celery = Celery(app.name, broker=app.config['CELERY_BROKER_URL'])
celery.conf.update(app.config)

正如你所见,Celery 通过创建一个 Celery 类对象来初始化,传入应用名称以及消息代理的连接 URL,这个 URL 我把它放在 app.config 中的 CELERY_BROKER_URL 的键值。URL 告诉 Celery 代理服务在哪里运行。如果你运行的不是 Redis,或者代理服务运行在一个不同的机器上,相应地你需要改变 URL。

Celery 其它任何配置可以直接用 celery.conf.update() 通过 Flask 的配置直接传递。CELERY_RESULT_BACKEND 选项只有在你必须要 Celery 任务的存储状态和运行结果的时候才是必须的。展示的第一个示例是不需要这个功能的,但是第二个示例是需要的,因此最好从一开始就配置好。

任何你需要作为后台任务的函数需要用 celery.task 装饰器装饰。例如:

@celery.task
def my_background_task(arg1, arg2):
    # some long running task here
    time.sleep(10)
    return result

接着 Flask 应用能够请求这个后台任务的执行,像这样:

task = my_background_task.delay(10, 20)

delay() 方法是强大的 apply_async() 调用的快捷方式。这样相当于使用 apply_async():

task = my_background_task.apply_async(args=[10, 20])

当使用 apply_async(),你可以给 Celery 后台任务如何执行的更详细的说明。一个有用的选项就是要求任务在未来的某一时刻执行。例如,这个调用将安排任务运行在大约一分钟后:

task = my_background_task.apply_async(args=[10, 20], countdown=60)

delay() 和 apply_async() 的返回值是一个表示任务的对象,这个对象可以用于获取任务状态。我将会在本文的后面展示如何获取任务状态等信息,但现在让我们保持简单些,不用担心任务的执行结果。

更多可用的选项请参阅 Celery 文档 。

flask 工厂模式使用celery

 在init中初始化celery实例:

#-*-coding:utf-8-*-
from celery import Celery

celery = Celery(__name__, broker='redis://127.0.0.1:6379/0',backend='redis://127.0.0.1:6379/0')

下面我们为 Celery 创建了一个工厂函数,在工厂函数中加载配置,并实现 Flask 程序上下文支持:

from flask import Flask
from flaskdemo.celery_task import celery

def make_celery(app):
    celery.conf.update(app.config)

    class ContextTask(celery.Task):
        def __call__(self, *args, **kwargs):
            with app.app_context():
                return self.run(*args, **kwargs)

    celery.Task = ContextTask
    return celery

在使用工厂函数的 Flask 程序中初始化 Celery

当 Flask 程序也使用工厂函数创建时,我们可以全局创建 Celery 程序实例,然后在创建 Flask 程序实例的工厂函数里更新 Celery 程序配置并进行上下文设置:

def create_app(config_name=None):
    if config_name is None:
        config_name = os.getenv('FLASK_CONFIG', 'development')

    app = Flask('flaskdemo')
    app.config.from_object(config[config_name])
    ...
    make_celery(app)
    return app

在定义 Celery 任务的模块里tasks.py:

# -*- coding: utf-8 -*-
import time
from celery import current_app as celery

def send_mail():
    time.sleep(20)
    print('邮件发送成功')

def send_sms():
    time.sleep(20)
    print('短信发送成功')

@celery.task
def send_new_sms():
    print('celery发送短信')
    send_sms()

@celery.task
def send_new_email():
    print('celery发送邮件')
    send_mail()

下来启动flask程序,启动celery,需要注意的是,celery在win环境中可以接受到任务,也有提示信息,但是任务没有执行,解决办法,启动的时候,使用eventlet 方式

celery -A flaskdemo.celery worker --loglevel=info -P eventlet -c 10

-c是协程的数量,生产环境可以用1000

原因:celery不支持在windows下运行任务,需要借助eventlet来完成。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值