Flask筆記-定時任務(wù)

一、什么是Celery?

Celery 是一個異步任務(wù)隊列。你可以使用它在你的應(yīng)用上下文之外執(zhí)行任務(wù)。總的想法就是你的應(yīng)用程序可能需要執(zhí)行任何消耗資源的任務(wù)都可以交給任務(wù)隊列,讓你的應(yīng)用程序自由和快速地響應(yīng)客戶端請求。

使用 Celery 運行后臺任務(wù)并不像在線程中這樣做那么簡單。但是好處多多,Celery 具有分布式架構(gòu),使你的應(yīng)用易于擴展。一個 Celery 安裝有三個核心組件:

  • Celery 客戶端: 用于發(fā)布后臺作業(yè)。當(dāng)與 Flask 一起工作的時候,客戶端與 Flask 應(yīng)用一起運行。
  • Celery workers: 這些是運行后臺作業(yè)的進程。Celery 支持本地和遠(yuǎn)程的 workers,因此你就可以在 Flask 服務(wù)器上啟動一個單獨的 worker,隨后隨著你的應(yīng)用需求的增加而新增更多的 workers。
  • 消息代理: 客戶端通過消息隊列和 workers 進行通信,Celery 支持多種方式來實現(xiàn)這些隊列。最常用的代理就是 RabbitMQRedis
二、簡單應(yīng)用

通過一個簡單例子,了解Flask的定時任務(wù),項目名稱:celery_demo,目錄結(jié)構(gòu)如下:
|---app
| |---__init__.py
| |---celery_manage
| | | ---- __init__.py
| | | ---- views.py
|---config.py
|---celery_worker.py

1. 安裝依賴包
pip install flask-celery-helper

另:Flask官網(wǎng)上的flask-celery包可能因為長期未維護的原因,在應(yīng)用中與python的celery包存在兼容問題,所以選擇了這個依賴包。

2. 編輯配置文件,config.py
#!/usr/bin/python
# -*- coding: utf-8 -*-
import os
from datetime import timedelta

basedir = os.path.abspath(os.path.dirname(__file__))

class Config:
    SECRET_KEY = os.environ.get('SECRET_KEY') or 'hard to guess string'
    # 定時任務(wù)配置
    CELERY_BROKER_URL = 'redis://localhost:6379',
    CELERY_RESULT_BACKEND = 'redis://localhost:6379'
    # CELERY_TIMEZONE = 'Asia/Shanghai'
    CELERYBEAT_SCHEDULE = {
        # 定義任務(wù)名稱:import_data
        # 執(zhí)行規(guī)則:每10秒運行一次
        'import_data': {
            'task': 'import_data',
            'schedule': timedelta(seconds=10)
        },
    }

    @staticmethod
    def init_app(app):
        pass

class DevelopmentConfig(Config):
    DEBUG = True
    SQLALCHEMY_DATABASE_URI = os.environ.get('TEST_DATABASE_URL') or \
                              'sqlite:///' + os.path.join(basedir, 'data-dev.sqlite')



class TestingConfig(Config):
    TESTING = True
    SQLALCHEMY_DATABASE_URI = os.environ.get('TEST_DATABASE_URL') or \
                              'sqlite:///' + os.path.join(basedir, 'data-test.sqlite')


class ProductionConfig(Config):
    SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL') or \
                              'sqlite:///' + os.path.join(basedir, 'data.sqlite')


config = {
    'development': DevelopmentConfig,
    'testing': TestingConfig,
    'production': ProductionConfig,
    'default': DevelopmentConfig
}

3. 創(chuàng)建celery管理的藍(lán)本,app/celery_manage/__init__.py
from flask import Blueprint
celery_manage = Blueprint('celery_manage', __name__)
from . import views
4. 初始化celery并注冊藍(lán)本到工廠函數(shù),app/__init__.py
#!/usr/bin/python
# -*- coding: utf-8 -*-
from flask import Flask
from config import config
from flask_celery import Celery

# 創(chuàng)建Celery實例
celery = Celery()

def create_app(config_name):
    app = Flask(__name__)
    app.config.from_object(config[config_name])
    config[config_name].init_app(app)
    celery.init_app(app)

    #注冊celery管理藍(lán)本
    from .celery_manage import celery_manage as celery_manage_blueprint
    app.register_blueprint(celery_manage_blueprint)

    return app
5. 添加定時任務(wù),app/celery_manage/views.py
#!/usr/bin/python
# -*- coding: utf-8 -*-
from app import celery
from celery.utils.log import get_task_logger

logger = get_task_logger(__name__)

# 定時導(dǎo)入
@celery.task(name="import_data")
def import_data():
    print "定時任務(wù):每10秒執(zhí)行一次"
    # 記錄日志
    logger.info(u"導(dǎo)入成功")

注:任務(wù)名稱為配置文件config.py中定義的名稱,即“import_data”

6. 編輯啟動應(yīng)用的接口文件,celery_worker.py
#!/usr/bin/python
# -*- coding: utf-8 -*-
from app import create_app, celery
import os

application = create_app(os.getenv('FLASK_CONFIG') or 'default')
application.app_context().push()

if __name__ == '__main__':
    application.run()
7. 運行celery,在終端輸入:
celery worker -l INFO -c 100 -A celery_worker.celery --beat

說明:

  • 參數(shù)-l INFO可以詳細(xì)輸出任務(wù)信息。
  • celery默認(rèn)會開啟4個線程來處理任務(wù),參數(shù)-c可以開啟更多任務(wù)線程。
  • 參數(shù)--beat:執(zhí)行定時任務(wù)時, Celery會通過celerybeat進程來完成。Celerybeat會保持運行, 一旦到了某一定時任務(wù)需要執(zhí)行時, Celerybeat便將其加入到queue中,適用于周期性任務(wù)。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容