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)