pip install apscheduler
触发器(triggers)
触发器就是根据你指定的触发方式,比如是按照时间间隔,还是按照 crontab触发,触发条件是什么等。每个任务都有自己的触发器。
触发器有三种,分别是:指定日期时间触发器(date)、时间间隔触发器(interval)、特定时间触发器(crontab)。
指定日期时间触发器(date)
在某个日期时间只触发一次事件。示例代码如下:
from datetime import datetime from apscheduler.schedulers.blocking import BlockingScheduler scheduler = BlockingScheduler() def my_job(text): print(text) # 触发类型 trigger_type = 'date' # 触发条件 trigger_props = { 'run_date': datetime.strptime('2022-05-24 17:40:00', '%Y-%m-%d %H:%M:%S') } scheduler.add_job(my_job, trigger_type, **trigger_props, args=['hello world']) scheduler.start()
时间间隔触发器(interval)
想要在固定的时间间隔触发事件。interval的触发条件可以设置以下的触发参数:
- weeks:周。整形。
- days:一个月中的第几天。整形。
- hours:小时。整形。
- minutes:分钟。整形。
- seconds:秒。整形。
- start_date:间隔触发的起始时间。
- end_date:间隔触发的结束时间。
- jitter:触发的时间误差。
示例代码如下:
# 触发类型 trigger_type = 'interval' # 触发条件 trigger_props = { 'minutes': 1 # 间隔1分钟运行(并不是每分钟的第一秒运行) } scheduler.add_job(my_job, trigger_type, **trigger_props, args=['hello world']) scheduler.start()
特定时间触发器(crontab)
在某个确切的时间周期性的触发事件。可以使用的参数如下:
- year:4位数字的年份。
- month:1-12月份。
- day:1-31日。
- week:1-53周。
- day_of_week:一个礼拜中的第几天( 0-6或者 mon、 tue、 wed、 thu、 fri、 sat、 sun)。
- hour: 0-23小时。
- minute: 0-59分钟。
- second: 0-59秒。
- start_date: datetime类型或者字符串类型,起始时间。
- end_date: datetime类型或者字符串类型,结束时间。
- timezone:时区。
- jitter:任务触发的误差时间。
也可以使用表达式类型,如下图所示:
示例代码如下:
# 触发类型 trigger_type = 'cron' # 触发条件 trigger_props = { # 指定年份 'year': 2022, # 指定3-6月 'month': '3-6', # 每周二、周三、周四 'day_of_week': 'tue,wed,thu', # 每小时 'hour': '*', # 第一分钟 'minute': '1', # 每隔5秒 'second': '*/5' } scheduler.add_job(my_job, trigger_type, **trigger_props, args=['hello world']) scheduler.start()
任务存储器(job stores)
任务存储器是可以存储任务的地方,默认情况下任务保存在内存,也可将任务保存在各种数据库中。任务存储进去后,会进行序列化,然后也可以反序列化提取出来,继续执行。
任务存储器的选择有两种。一是内存,也是默认的配置。二是数据库。使用内存的方式是简单高效,但是不好的是,一旦程序出现问题,重新运行的话,会把之前已经执行了的任务重新执行一遍。数据库则可以在程序崩溃后,重新运行可以从之前中断的地方恢复正常运行。有以下几种选择:
- MemoryJobStore:没有序列化,任务存储在内存中,增删改查都是在内存中完成。
- SQLAlchemyJobStore:使用 SQLAlchemy这个 ORM框架作为存储方式。
- MongoDBJobStore:使用 MongoDB作为存储器。
- RedisJobStore:使用 redis作为存储器。
执行器(executors)
执行器的目的是安排任务到线程池或者进程池中运行的。
执行器的选择取决于应用场景。通常默认的 ThreadPoolExecutor已经在大部分情况下是可以满足我们需求的。如果我们的任务涉及到一些 CPU密集计算的操作。那么应该考虑 ProcessPoolExecutor。然后针对每种程序, apscheduler也设置了不同的 executor:
- ThreadPoolExecutor:线程池执行器。
- ProcessPoolExecutor:进程池执行器。
- GeventExecutor: Gevent程序执行器。
- TornadoExecutor: Tornado程序执行器。
- TwistedExecutor: Twisted程序执行器。
- AsyncIOExecutor: asyncio程序执行器。
调度器(schedulers)
任务调度器是属于整个调度的总指挥官。他会合理安排作业存储器、执行器、触发器进行工作,并进行添加和删除任务等。调度器通常是只有一个的。开发人员很少直接操作触发器、存储器、执行器等。因为这些都由调度器自动来实现了。
常见的调度器如下:
- BlockingScheduler:适用于调度程序是进程中唯一运行的进程,调用 start函数会阻塞当前线程,不能立即返回。
- BackgroundScheduler:适用于调度程序在应用程序的后台运行,调用 start后主线程不会阻塞。
- AsyncIOScheduler:适用于使用了 asyncio模块的应用程序。
- GeventScheduler:适用于使用 gevent模块的应用程序。
- TwistedScheduler:适用于构建 Twisted的应用程序。
- QtScheduler:适用于构建 Qt的应用程序。