APScheduler_定时框架入门

jefxff 153,864 2020-02-10

APScheduler 是一个跨平台的定时框架

安装

	pip install apscheduler

理解基本概念

1. 触发器 (triggers)

触发器包含调度逻辑。 每个作业都有自己的触发器,用于确定何时应该运行作业。 除了初始配置之外,触发器完全是无状态的。

2. 作业存储器 (job stores)

作业存储器安排预定的工作。 默认作业存储只是将作业保留在内存中,但也可以将它们存储在各种类型的数据库中。 作业的数据在保存到持久性作业存储时会被序列化,并在从其中加载时进行反序列化。 作业存储(默认存储除外)不会将作业数据保留在内存中,而是充当中间人,用于在后端保存,加载,更新和搜索作业。 绝不能在调度程序之间共享作业存储。

3. 执行器 (executors)

执行器是将指定的作业(调用函数)提交到线程池或进程池中运行,当任务完成时,执行器通知调度器触发相应的事件。

4. 调度器 (schedulers)

通过它配置作业存储器、执行器和触发器,添加、修改和删除任务。调度器协调触发器、作业存储器、执行器的运行,通常只有一个调度程序运行在应用程序中,开发人员通常不需要直接处理作业存储器、执行器或触发器,配置作业存储器和执行器是通过调度器来完成的。

常见的调度器

  • BlockingScheduler: 阻塞式调度器, 适用于只跑调度器的程序
	from apscheduler.schedulers.blocking import BlockingScheduler
  • BackgroundScheduler: 后台调度器, 适用于非阻塞的情况,调度器会在后台独立运行
	from apscheduler.schedulers.background import BackgroundScheduler
  • AsyncIOScheduler:适合于使用asyncio框架(一个异步框架)的情况
  • GeventScheduler: 适合于使用gevent框架(高性能的Python并发框架)的情况
  • TornadoScheduler: 适合于使用Tornado框架(一个web框架)的应用
  • TwistedScheduler: 适合使用Twisted框架的应用
  • QtScheduler: 适合使用QT的情况

选择合适的触发器

1. date: 想让程序在在某个固定的时间运行
	# 只写主要程序
 	# 给触发器传入'date', 表示在2019年8月8日 凌晨01:00:00执行一次
    scheduler.add_job(main, 'date', run_date='2019-08-08 01:00:00')
2. interval:想让程序以固定的时间间隔运行
	# 给触发器传入'interval', 表示自从运行程序开始, 每隔120秒就执行一次
    scheduler.add_job(main, 'interval', seconds=120)
3. cron:想让程序在一天中的某个时间定期运行
	# 给触发器传入'cron',表示每天的17:10分执行任务,时间可以是数字,也可是字符串
    scheduler.add_job(main, 'cron', hour=17, minute=10 )
4. calendarinterval:当您想要在一天中的特定时间以日历为基础的间隔运行作业时使用

配置调度程序

APScheduler提供了许多不同的方法来配置调度程序。您可以使用配置字典,也可以将选项作为关键字参数传递。您还可以先实例化调度程序,然后添加作业并配置调度程序。

# 导入模块
from apscheduler.schedulers.blocking import BlockingScheduler
from datetime import datetime

# 定义一个拟调度的函数
def get_now_time():
    return datetime.now().strftime('%Y-%m-%d %H:%M:%S')

if __name__ == "__main__":
	# 实例化一个调度程序
	scheduler = BlockingScheduler()
	# 给调度器添加作业, 给触发器传递 "cron", 表示在每天的17:10分执行任务
	scheduler.add_job(get_now_time, 'cron', hour=17, minute=10 )
	# 启动调度程序
    scheduler.start()

启动调度器

启动调度器是只需调用start()即可。除了BlockingScheduler,非阻塞调度器都会立即返回,可以继续运行之后的代码,比如添加任务等。

添加任务

  1. 最常用 add_job() 会返回一个apscheduler.job.Job实例,这样就可以在运行时,修改或删除任务。
  2. 最方便 scheduled_job() 但是运行时,不能修改任务。

移除任务

  1. 调用remove_job(),参数为:任务ID,任务储存器名称
	job = scheduler.add_job(get_now_time, 'cron', hour=17, minute=10 )
	job.remove()
  1. 在通过add_job()创建的任务实例上调用remove()方法
	scheduler.add_job(get_now_time, 'interval', minutes=2, id='my_job_id')
	scheduler.remove_job('my_job_id')

暂停/恢复任务

通过任务实例或调度器,就能暂停和恢复任务。如果一个任务被暂停了,那么该任务的下一次运行时间就会被移除。在恢复任务前,运行次数计数也不会被统计。

  1. 暂停任务
	#暂停任务,有以下两个方法:
	apscheduler.job.Job.pause()
	apscheduler.schedulers.base.BaseScheduler.pause_job()
  1. 恢复任务
	apscheduler.job.Job.resume()
	apscheduler.schedulers.base.BaseScheduler.resume_job()

获取/打印任务列表

  1. 获取任务列表
    通过get_jobs()就可以获得一个可修改的任务列表。get_jobs()第二个参数可以指定任务储存器名称,那么就会获得对应任务储存器的任务列表。
  2. 打印任务列表
    print_jobs()可以快速打印格式化的任务列表,包含触发器,下次运行时间等信息。

修改任务

  1. 通过apscheduler.job.Job.modify()或modify_job(),你可以修改任务当中除了id的任何属性。
	# max_instances参数, 指定任务设置最大实例并行数
	job.modify(max_instances=6, name='Alternate name')
  1. 通过apscheduler.job.Job.reschedule()或reschedule_job()来重新调度任务(就是改变触发器)
	scheduler.reschedule_job('my_job_id', trigger='cron', minute='*/5')	

关闭调度器

默认情况下,调度器会先把正在执行的任务处理完,再关闭任务储存器和执行器。但是,如果你就直接关闭可添加参数 wait=False

	scheduler.shutdown(wait=False)

暂停/恢复任务进程

  1. 暂停任务
	scheduler.pause()
  1. 恢复任务
	scheduler.resume()

	# 可以在调度器启动时,默认所有任务设为暂停状态
	scheduler.start(paused=True)

# python