Python 定时框架 APScheduler技术原理

1.APscheduler是什么

Python定时任务框架APScheduler,Advanced Python Scheduler (APScheduler) 是一个轻量级但功能强大的进程内任务调度器,作用为在指定的时间规则执行指定的作业(时间规则:指定的日期时间、固定时间间隔以及类似Linux系统中Crontab的方式);并且该框架可以进行持久化配置,保证在项目重启或者崩溃恢复后仍然能够恢复之前的作业继续运行。

2.APScdeduler的基本概念

2.1 Job 作业

包含要执行的任务(函数),任务执行所需要的参数,以及调度器执行该任务所需要的一些额外的配置信息,比如什么时间点执行?任务信息保存在哪里,内存还是数据库等?使用线程执行还是进程执行?

Job的属性包括:

  • id:指定作业的唯一ID
  • name:指定作业的名字
  • trigger:触发器,分为date,interval,cron三种触发器,主要的作用就是根据设置的时间规则就是计算出任务的下一次触发时间。
  • executor:执行器,负责处理作业的运行,通常使用的是线程池或进程池。当作业完成时,执行器将会通知调度器。
  • max_instances:每个job在同一时刻能够运行的最大实例数,默认情况下为1个,可以指定为更大值,这样即使上个job还没运行完同一个job又被调度的话也能够再开一个线程执行
  • next_run_time:Job下次的执行时间,创建Job时可以指定一个时间[datetime],不指定的话则默认根据trigger获取触发时间。
  • misfire_grace_time:Job的延迟执行时间,例如Job的计划执行时间是21:00:00,但因服务重启或其他原因导致21:00:31才执行,如果设置此key为40,则该job会继续执行,否则将会丢弃此job。
  • coalesce:Job是否合并执行,是一个bool值。例如scheduler停止20s后重启启动,而job的触发器设置为5s执行一次,因此此job错过了4个执行时间,如果设置为是,则会合并到一次执行,否则会逐个执行。
  • func:Job执行的函数。
  • args:Job执行函数需要的位置参数。
  • kwargs:Job执行函数需要的关键字参数。

2.2 Trigger 触发器

Trigger绑定到Job,在scheduler调度筛选Job时,根据触发器的规则计算出Job的触发时间,然后与当前时间比较确定此Job是否会被执行,总之就是根据trigger规则计算出下一个执行时间。

目前APScheduler支持触发器:

  • DateTrigger: 指定日期时间执行一次
  • IntervalTrigger: 固定时间间隔执行,支持每秒、每分、每时、每天、每周
  • CronTrigger: 类似Linux系统的Crontab定时任务

DateTrigger和IntervalTrigger很好理解,使用也比较简单,这里重点说一下CronTrigger触发器。

CronTrigger触发器的参数选项如下:

字段 类型 说明
year int | string 年,4位数字
month int | string 月 (范围1-12或者jan– dec)
day int | string 日 (范围1-31)
week int | string 周 (范围1-53)
day_of_week int | string 星期几 (范围0-6 或者 mon - sun)
hour int | string 时 (范围0-23)
minute int | string 分 (范围0-59)
second int | string 秒 (范围0-59)
start_date datetime | string 最早开始日期(包含)
end_date datetime | string 最晚结束时间(包含)
timezone datetime.tzinfo | string 指定时区

CronTrigger可用的表达式:

表达式 参数类型 描述
* 所有 通配符。例:minutes=*即每分钟触发
* / a 所有 每隔时长a执行一次。例:minutes="* / 3" 即每隔3分钟执行一次
a - b 所有 a - b的范围内触发。例:minutes=“2-5”。即2到5分钟内每分钟执行一次
a - b / c 所有 a - b范围内,每隔时长c执行一次。
xth y 第几个星期几触发。x为第几个,y为星期几
last x 一个月中,最后一个星期的星期几触发
last 一个月中的最后一天触发
x, y, z 所有 组合表达式,可以组合确定值或上述表达式

注:

1.当省略时间参数时,在显式指定参数之前的参数会被设定为*,之后的参数会被设定为最小值,week 和day_of_week的最小值为*。比如,设定day=1, minute=20等同于设定year=’*’, month=’*’, day=1, week=’*’, day_of_week=’*’, hour=’*’, minute=20, second=0,即每个月的第一天,且当分钟到达20时就触发。

2.如果要实现每隔一段时间执行一次的任务,有时候使用CronTriger并不合适,例如我们设定hour=’*/15’,希望任务每隔15小时执行一次,但实际上,这个表达式的意思是0-23小时内,每隔15小时执行一次,也就是每天的0:00, 15:00会执行一次; 并不会按照预期一样0:00执行一次,15:00执行一次,第二天的6:00再执行一次…

三种触发器的使用示例:

from datetime import datetime
from apscheduler.schedulers.blocking import BlockingScheduler


def task():
    print("Hello World")


if __name__ == '__main__':

    scheduler = BlockingScheduler()

    # DateTrigger 2020-12-12 00:00:00执行一次
    scheduler.add_job(task, 'date', id='date_job', run_date=datetime(2020, 12, 12, 0, 0, 0))

    # IntervalTrigger 每隔两秒执行一次
    scheduler.add_job(task, 'interval', id='interval_job', seconds=2)

    # CronTrigger 每周一到周五的5-10小时区间内,每两个小时的半点执行 一次
    scheduler.add_job(task, 'cron', id='cron_job_01', day_of_week='mon_fri', hour='5-10/2', minute=30)

    # CronTrigger 6,7,8,11,12月的第三个周五的 01:00, 02:00, 03:00执行
    scheduler.add_job(task, 'cron', id='cron_job_02', month='6-8, 11-12', day='3rd fri', hour='1-3')

    scheduler.start()

2.3 Executor 执行器

负责处理作业的运行,通常使用的是ThreadPoolExecutor或ProcessPoolExecutor。当作业完成时,执行器将会通知调度器。

大多数情况下, 执行器 选择 ThreadPoolExecutor 就够用了,但如果涉及到CPU密集的作业,就可以选择ProcessPoolExecutor,以充分利用多核CPU。当然也可以同时配置使用两个执行器,将进程池 ProcessPoolExecutor 调度器作为你的第二个执行器。

2.4 Jobstore 作业存储器

保存要调度的任务,其中除了默认的作业存储是把作业保存在内存中,其他的作业存储是将作业保存在数据库中。一个作业的数据将在保存在持久化的作业存储之前,会对作业执行序列化操作,当重新读取作业时,再执行反序列化操作。

目前APScheduler支持的Jobstore:

  • MemoryJobStore
  • MongoDBJobStore
  • <
  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值