APScheduler使用总结
安装
pip install apscheduler
APScheduler组件
1、triggers(触发器)
触发器中包含调度逻辑,每个作业都由自己的触发器来决定下次运行时间。除了他们自己初始配置意外,触发器完全是无状态的。
(1)interval 间隔调度(每隔多久执行)
- weeks (int) – 间隔几周
- days (int) – 间隔几天
- hours (int) – 间隔几小时
- minutes (int) – 间隔几分钟
- seconds (int) – 间隔多少秒
- start_date (datetime|str) – 开始日期
- end_date (datetime|str) – 结束日期
- timezone (datetime.tzinfo|str) – 时区
# 每两个小时调一下job_function sched.add_job(job_function, 'interval', hours=2)
(2)cron定时调度(某一定时时刻执行)
(int|str) 表示参数既可以是int类型,也可以是str类型
(datetime | str) 表示参数既可以是datetime类型,也可以是str类型
- year (int|str) – 4-digit year -(表示四位数的年份,如2008年)
- month (int|str) – month (1-12) -(表示取值范围为1-12月)
- day (int|str) – day of the (1-31) -(表示取值范围为1-31日)
- week (int|str) – ISO week (1-53) -(格里历2006年12月31日可以写成2006年-W52-7(扩展形式)或2006W527(紧凑形式))
- day_of_week (int|str) – number or name of weekday (0-6 or mon,tue,wed,thu,fri,sat,sun) - (表示一周中的第几天,既可以用0-6表示也可以用其英语缩写表示)
- hour (int|str) – hour (0-23) - (表示取值范围为0-23时)
- minute (int|str) – minute (0-59) - (表示取值范围为0-59分)
- second (int|str) – second (0-59) - (表示取值范围为0-59秒)
- start_date (datetime|str) – earliest possible date/time to trigger on (inclusive) - (表示开始时间)
- end_date (datetime|str) – latest possible date/time to trigger on (inclusive) - (表示结束时间)
- timezone (datetime.tzinfo|str) – time zone to use for the date/time calculations (defaults to scheduler timezone) -(表示时区取值)
参数的取值格式:
Expression |
Field |
Description |
* |
any |
Fire on every value |
*/a |
any |
Fire every a values, starting from the minimum |
a-b |
any |
Fire on any value within the a-b range (a must be smaller than b) |
a-b/c |
any |
Fire every c values within the a-b range |
xth y |
day |
Fire on the x -th occurrence of weekday y within the month |
last x |
day |
Fire on the last occurrence of weekday x within the month |
last |
day |
Fire on the last day within the month |
x,y,z |
any |
Fire on any matching expression; can combine any number of any of the above expressions |
#表示2017年3月22日17时19分07秒执行该程序 sched.add_job(my_job, 'cron', year=2017,month = 03,day = 22,hour = 17,minute = 19,second = 07) #表示任务在6,7,8,11,12月份的第三个星期五的00:00,01:00,02:00,03:00 执行该程序 sched.add_job(my_job, 'cron', month='6-8,11-12', day='3rd fri', hour='0-3') #表示从星期一到星期五5:30(AM)直到2014-05-30 00:00:00 sched.add_job(my_job(), 'cron', day_of_week='mon-fri', hour=5, minute=30,end_date='2014-05-30') #表示每5秒执行该程序一次,相当于interval 间隔调度中seconds = 5 sched.add_job(my_job, 'cron',second = '*/5')
(3)date 定时调度(作业只会执行一次)
run_date (datetime|
str
) – the date
/
time to run the job at
-
(任务开始的时间)
timezone (datetime.tzinfo|
str
) – time zone
for
run_date
if
it doesn’t have one already
#在指定的时间,只执行一次 scheduler.add_job(tick, 'date', run_date='2016-02-14 15:01:05') # The job will be executed on November 6th, 2009 sched.add_job(my_job, 'date', run_date=date(2009, 11, 6), args=['text']) # The job will be executed on November 6th, 2009 at 16:30:05 sched.add_job(my_job, 'date', run_date=datetime(2009, 11, 6, 16, 30, 5), args=['text'])
2、job stores(作业存储器)
存储被调度的作业,默认的作业存储器只是简单地把作业保存在内存中,其他的作业存储器则是将作业保存在数据库中。当作业被保存到一个持久化的作业存储器中的时候,该作业的数据会被序列化,并在加载时被反序列化。作业存储器不能共享调度器。
jobstore提供给scheduler一个序列化jobs的统一抽象,提供对scheduler中job的增删改查接口,根据存储backend的不同,分以下几种:
- MemoryJobStore:没有序列化,jobs就存在内存里,增删改查也都是在内存中操作
- SQLAlchemyJobStore:所有sqlalchemy支持的数据库都可以做为backend,增删改查操作转化为对应backend的sql语句,用于支持大多数RDBMS
- MongoDBJobStore:用mongodb作backend
- RedisJobStore: 用redis作backend
- ZooKeeperJobStore:用ZooKeeper做backend
3、executors(执行器)
处理作业的运行,他们通常通过在作业中提交指定的可调用对象到一个线程或者进城池来进行。当作业完成时,执行器将会通知调度器。
4、schedulers(调度器)
配置作业存储器和执行器可以在调度器中完成,例如添加、修改和移除作业。根据不同的应用场景可以选用不同的调度器。
可选的有BlockingScheduler、BackgroundScheduler、AsyncIOScheduler、GeventScheduler、TornadoScheduler、TwistedScheduler、QtScheduler 7种。
- BlockingScheduler : main_loop就在当前进程的主线程内运行,所以调用start函数后会阻塞当前线程。通过一个threading.Event条件变量对象完成scheduler的定时唤醒。
- BackgroundScheduler : 和BlockingScheduler基本一样,除了main_loop放在了单独线程里,所以调用start后主线程不会阻塞.
- AsyncIOScheduler : 当你的程序使用了asyncio(一个异步框架)的时候使用。 使用asyncio作为IO模型的scheduler,和AsyncIOExecutor配合使用,用asynio中event_loop的call_later完成定时唤醒。
- GeventScheduler : 当你的程序使用了gevent(高性能的Python并发框架)的时候使用。 和BlockingScheduler基本一样,使用gevent作为IO模型,和GeventExecutor配合使用。
- TornadoScheduler : 当你的程序基于Tornado(一个web框架)的时候使用。使用tornado的IO模型,用ioloop.add_timeout完成定时唤醒。
- TwistedScheduler : 当你的程序使用了Twisted(一个异步框架)的时候使用。用reactor.callLater完成定时唤醒。
- QtScheduler : 如果你的应用是一个Qt应用的时候可以使用。 使用QTimer完成定时唤醒。
简单实例
import time from apscheduler.schedulers.blocking import BlockingScheduler def test_job(): print time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())) scheduler = BlockingScheduler() #该示例代码生成了一个BlockingScheduler调度器,使用了默认的默认的任务存储MemoryJobStore,以及默认的执行器ThreadPoolExecutor,并且最大线程数为10。 scheduler.add_job(test_job, 'interval', seconds=5, id='test_job') #该示例中的定时任务采用固定时间间隔(interval)的方式,每隔5秒钟执行一次。 #并且还为该任务设置了一个任务id scheduler.start()
如果想执行一些复杂任务,如上边所说的同时使用两种执行器,或者使用多种任务存储方式,并且需要根据具体情况对任务的一些默认参数进行调整。可以参考下面的方式。
(http://apscheduler.readthedocs.io/en/latest/userguide.html)
from pytz import utc from apscheduler.schedulers.background import BackgroundScheduler # 导入调度器 from apscheduler.jobstores.mongodb import MongoDBJobStore # 导入作业存储 from apscheduler.jobstores.sqlalchemy import SQLAlchemyJobStore # 导入作业存储 from apscheduler.executors.pool import ThreadPoolExecutor, ProcessPoolExecutor # 导入执行器 jobstores = { 'mongo': MongoDBJobStore(), 'default': SQLAlchemyJobStore(url='sqlite:///jobs.sqlite') } executors = { 'default': ThreadPoolExecutor(20), 'processpool': ProcessPoolExecutor(5) } job_defaults = { 'coalesce': False, 'max_instances': 3 } scheduler = BackgroundScheduler(jobstores=jobstores, executors=executors, job_defaults=job_defaults, timezone=utc)
from apscheduler.schedulers.background import BackgroundScheduler # The "apscheduler." prefix is hard coded scheduler = BackgroundScheduler({ 'apscheduler.jobstores.mongo': { 'type': 'mongodb' }, 'apscheduler.jobstores.default': { 'type': 'sqlalchemy', 'url': 'sqlite:///jobs.sqlite' }, 'apscheduler.executors.default': { 'class': 'apscheduler.executors.pool:ThreadPoolExecutor', 'max_workers': '20' }, 'apscheduler.executors.processpool': { 'type': 'processpool', 'max_workers': '5' }, 'apscheduler.job_defaults.coalesce': 'false', 'apscheduler.job_defaults.max_instances': '3', 'apscheduler.timezone': 'UTC', })
from pytz import utc from apscheduler.schedulers.background import BackgroundScheduler from apscheduler.jobstores.sqlalchemy import SQLAlchemyJobStore from apscheduler.executors.pool import ProcessPoolExecutor jobstores = { 'mongo': {'type': 'mongodb'}, 'default': SQLAlchemyJobStore(url='sqlite:///jobs.sqlite') } executors = { 'default': {'type': 'threadpool', 'max_workers': 20}, 'processpool': ProcessPoolExecutor(max_workers=5) } job_defaults = { 'coalesce': False, 'max_instances': 3 } scheduler = BackgroundScheduler() # .. do something else here, maybe add jobs etc. scheduler.configure(jobstores=jobstores, executors=executors, job_defaults=job_defaults, timezone=utc)