在我们的开发工作中,时常会有这样的开发需求,如需要定时或者周期性的运行某些程序,因此经常用到一些定时服务,如在 Linux系统中使用 Crond 服务实现程序的定时运行。
在 Python中也有这样的一个模块,那就是 APScheduler,它是基于Quartz 的一个 Python定时任务框架,实现了 Quartz的全部功能,使用起来十分简单、高效。其提供了基于日期、固定时间间隔以及 Crontab类型的任务,并且支持持久化任务。同时也提供了不同的存储机制,可以方便与数据库等第三方的外部持久化存储进行协同工作。它主要包含了四种组件:
- Triggers:任务触发器,任务以何种方式触发。
- Job stores:任务存储器,持久存储任务。
- Executors:任务执行器,执行任务的模块。
- Schedulers:任务调度器,通过配置 trigger、job store、executor等实现对任务的增删改查等调度控制。
APScheduler安装
安装过程如下:
任务存储器 Job stores
Job stores 存储被调度的任务,默认的任务存储是简单地把任务保存在内存(MemoryJobStore)中,其他的任务存储形式是将任务保存在数据库中。一个任务的数据将在保存在持久化任务存储时被序列化,在加载时被反序列化。调度器不能分享同一个任务存储。job store支持主流的存储机制:redis、mongodb、内存等等。
以 MongoDBJobStore为例,实例如下:
执行器 Executors
Executors 处理任务的运行,他们通常通过在任务中提交制定的可调用对象到一个线程或者进城池来进行,当任务完成时,执行器将会通知调度器。
调度器 Schedulers
通常在应用只有一个调度器,调度器提供了处理任务存储、调度器、触发器合适的接口。配置任务存储和执行器可以在调度器中完成,例如添加、修改和移除任务。常用的调度器如下:
- BlockingScheduler:仅可用在当前你的进程之内,与当前的进行共享计算资源,适合于只在进程中运行单个任务的情况,通常在调度器是你唯一要运行的东西时使用。
- BackgroundScheduler: 在后台运行调度,不影响当前的系统计算运行,适合于要求任何在程序后台运行的情况,当希望调度器在应用后台执行时使用。
- AsyncIOScheduler: 如果当前系统中使用了async module,则需要使用异步的调度器,适合于使用asyncio框架的情况。
- GeventScheduler: 如果使用了 gevent,则需要使用该调度,适合于使用 gevent框架的情况。
- TornadoScheduler: 如果使用了Tornado, 则使用当前的调度器,适合于使用 Tornado框架的应用。
- TwistedScheduler:Twister应用的调度器,适合使用Twisted框架的应用。
- QtScheduler: Qt的调度器,适合使用QT的情况。
触发器种类Triggers
Triggers 包含调度逻辑,每一个任务有它自己的触发器,用于决定接下来哪一个任务运行,根据 Triggers 中定义的时间点,执行频率,时间区间等等参数设置。除了他们自己初始配置以外,触发器完全是无状态的,触发器有如下几种:
- date:一次性任务,即只执行一次任务。
- interval:循环任务,即按照时间间隔执行任务。
- cron:定时任务,即在每个时间段执行任务。
interval 触发器实例
指定触发器为 interval,循环任务,即按照 时间间隔 执行任务。
参数如下
- year (int|str) :表示四位数的年份,如2019年
- month (int|str) :表示取值范围为1-12月。
- day (int|str) :表示取值范围为1-31日。
- week (int|str) :一年中的第几周 (1-53)。
- day_of_week (int|str) :表示一周中的第几天(0-6)。
- hour (int|str):表示取值范围为0-23时。
- minute (int|str) :表示取值范围为0-59分。
- second (int|str) :表示取值范围为0-59秒。
- start_date (datetime|str) :表示开始时间。
- end_date (datetime|str) :表示结束时间。
- timezone (datetime.tzinfo|str) :表示时区取值。
如上,我们设定 每2秒执行一次,运行结果如下:
date 触发器实例
指定触发器为 date,一次性任务,即只执行一次任务。
如上,我们设定任务 延时五秒 后执行,运行结果如下:
cron 触发器实例
指定触发器为 cron,定时任务,即在每个时间段执行任务。
参数如下
- year (int|str) :表示四位数的年份,如2019年
- month (int|str) :表示取值范围为1-12月。
- day (int|str) :表示取值范围为1-31日。
- week (int|str) :一年中的第几周 (1-53)。
- day_of_week (int|str) :表示一周中的第几天(0-6)。
- hour (int|str):表示取值范围为0-23时。
- minute (int|str) :表示取值范围为0-59分。
- second (int|str) :表示取值范围为0-59秒。
- start_date (datetime|str) :表示开始时间。
- end_date (datetime|str) :表示结束时间。
- timezone (datetime.tzinfo|str) :表示时区取值。
如上,我们设定在2、4月、7~9月,每天晚上22点21分执行一次任务,运行结果如下:
移除、暂停/恢复任务