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的应用程序。