• APscheduler总结


    APscheduler使用总结

    APscheduler是执行定时任务的python库,其作用可以代替Linux系统下的crontab,github上有该库的例子

    APsheduler基本使用

    该模块由4个基本组件组成:

    • triggers 触发器
    • job stores 任务储存
    • executors 执行器
    • schedulers 调度器

    其中triggers定义了定时任务的类别、触发条件以及具体要执行的任务名。
    job stores可以将任务储存起来,有些需要重复执行的任务,或有数据生成的任务,有将数据储存的要求,可以通过数据库或文件的形式将数据储存起来以便下次使用。
    executors负责具体的任务执行。
    schedulers是最高级的组件,负责其它的管理和调度工作,该模块有几种可选的调度器可供选择,使用方法都是一样的:

    BlockingScheduler: use when the scheduler is the only thing running in your process
    BackgroundScheduler: use then you’re not using any of the frameworks below, and want the scheduler to run in the background inside your application
    AsyncIOScheduler: use if your application uses the asyncio module
    GeventScheduler: use if your application uses gevent
    TornadoScheduler: use if you’re building a Tornado application
    TwistedScheduler: use if you’re building a Twisted application
    QtScheduler: use if you’re building a Qt application
    

    定时任务的执行内容放在一个函数中使用,而调度的类型和时间等设置则在创建这个job的时候进行定义,在这个模块中,一个具体的任务是一个JOB实例,因此可以通过修改这个实例的属性对任务进行重新设置,而每一个job实例都是依赖于一个scheduler,所以也可以通过sheduler对sheduler进行重新设定。

    定时任务的类型说明

    参考源码中scheduler.add_job()的参数说明
    'cron'跟linux下crontab一样的定时类型写法,
    'interval'使用时间间隔的写法
    ...

    说明

    from apscheduler.schedulers.background import BackgroundScheduler
    
    # 创建scheduler
    scheduler = BackgroundScheduler()
    
    # 创建job
    # 方法1
    job = scheduler.add_job(myfunc, 'interval', minutes=2, id='my_job_id')
    # 方法2
    @scheduler.scheduled_job
    def myfunc():
        # do something
    	pass
    	
    # 启动
    scheduler.start()
    
    # 添加job
    scheduler.add_job(myfunc, 'interval', minutes=2, id='my_job_id')
    # 删除job
    scheduler.remove_job('my_job_id')
    # 暂停job
    scheduler.pause_job()
    # 恢复job
    scheduler.resume_job()
    # 查看jobs
    scheduler.get_jobs()
    scheduler.print_jobs()
    # 修改job
    scheduler.modify_job(max_instances=6, name='Alternate name')
    # 重新设置定时任务类型
    scheduler.reschedule_job('my_job_id', trigger='cron', minute='*/5')
    
    # 关闭
    scheduler.shutdown(wait=False)
    

    scheduler配置

    配置内容

    • a MongoDBJobStore named “mongo”
    • an SQLAlchemyJobStore named “default” (using SQLite)
    • a ThreadPoolExecutor named “default”, with a worker count of 20
    • a ProcessPoolExecutor named “processpool”, with a worker count of 5
    • utc标准时区
    • coalescing turned off for new jobs by default
    • 默认最多3个jobs

    方法1

    from pytz import utc
    from apscheduler.schedulers.background import BackgroundScheduler
    from apscheduler.jobstores.mongodb import MongoDBJobStore
    from apscheduler.jobstores.sqlalchemy import SQLAlchemyJobStore
    from apscheduler.executors.pool import ThreadPoolExecutor, ProcessPoolExecutor
    
    jobstores = {
        'mongo': MongoDBJobStore(),
        'default': SQLAlchemyJobStore(url='sqlite:///jobs.sqlite')
    }
    executors = {
        'default': ThreadPoolExecutor(20),
        'processpool': ProcessPoolExecutor(5)
    }
    job_defaults = {
        'coalesce': False,
        'max_instances': 3
    }
    scheduler = BackgroundScheduler(jobstores=jobstores, executors=executors, job_defaults=job_defaults, timezone=utc)
    
    

    方法2

    from apscheduler.schedulers.background import BackgroundScheduler
    
    
    # The "apscheduler." prefix is hard coded
    scheduler = BackgroundScheduler({
        'apscheduler.jobstores.mongo': {
             'type': 'mongodb'
        },
        'apscheduler.jobstores.default': {
            'type': 'sqlalchemy',
            'url': 'sqlite:///jobs.sqlite'
        },
        'apscheduler.executors.default': {
            'class': 'apscheduler.executors.pool:ThreadPoolExecutor',
            'max_workers': '20'
        },
        'apscheduler.executors.processpool': {
            'type': 'processpool',
            'max_workers': '5'
        },
        'apscheduler.job_defaults.coalesce': 'false',
        'apscheduler.job_defaults.max_instances': '3',
        'apscheduler.timezone': 'UTC',
    })
    

    方法3

    from pytz import utc
    
    from apscheduler.schedulers.background import BackgroundScheduler
    from apscheduler.jobstores.sqlalchemy import SQLAlchemyJobStore
    from apscheduler.executors.pool import ProcessPoolExecutor
    
    
    jobstores = {
        'mongo': {'type': 'mongodb'},
        'default': SQLAlchemyJobStore(url='sqlite:///jobs.sqlite')
    }
    executors = {
        'default': {'type': 'threadpool', 'max_workers': 20},
        'processpool': ProcessPoolExecutor(max_workers=5)
    }
    job_defaults = {
        'coalesce': False,
        'max_instances': 3
    }
    scheduler = BackgroundScheduler()
    
    # .. do something else here, maybe add jobs etc.
    
    scheduler.configure(jobstores=jobstores, executors=executors, job_defaults=job_defaults, timezone=utc)
    
    

    flask下使用APscheduler

    flask下使用该模块可以使用flask扩展模块flask-apsheduler

    基本使用

    from flask import Flask
    from flask_apscheduler import APScheduler
    
    
    class Config(object):
        JOBS = [
            {
                'id': 'job1',
                'func': 'jobs:job1',
                'args': (1, 2),
                'trigger': 'interval',
                'seconds': 10
            }
        ]
    
        SCHEDULER_API_ENABLED = True
    
    
    def job1(a, b):
        print(str(a) + ' ' + str(b))
    
    if __name__ == '__main__':
        app = Flask(__name__)
        app.config.from_object(Config())
    
        scheduler = APScheduler()
        # it is also possible to enable the API directly
        # scheduler.api_enabled = True
        scheduler.init_app(app)
        scheduler.start()
        app.run()
    

    故障排除

    在使用gunicorn对flask进行管理的时候如何保证只定时任务只启动一次

    问题在使用gunicorn对flask应用进行控制的时候如果设置了gunicorn的--worker参数大于1时,会出现一个定时任务执行多次的问题,此时要给gunicorn提供一个额外的--preload参数,这样,flask的app在run之前的所有操作只会执行一次,因此定时任务就只会执行一次。
    env/bin/gunicorn module_containing_app:app -b 0.0.0.0:8080 --workers 3 --preload

    flask在调试模式下调用flask-apscheduler定时任务时会执行多次

    问题与上面的问题类似,调试模式下只需给app.run()添加一个参数use_reloader即可。
    app.run(debug=True, use_reloader=False)

  • 相关阅读:
    retain和copy的区别 #import @class 的区别
    UImageview加边框 加阴影
    iOS中有两种支持机制:Notification和KVO(KeyValue Observing)
    Windows上编译,学习Objectivec
    CAAnimation动画
    ObjectiveC 熟记小概念
    cocos2d工具大全
    cocos2d 0.99.5版本屏幕默认是横屏,怎么修改为竖屏呢?
    ObjectiveC 的 self 和 super 详解
    ObjectiveC 的属性与合成方法使用详解
  • 原文地址:https://www.cnblogs.com/zhangjpn/p/7226747.html
Copyright © 2020-2023  润新知