言
APScheduler是Python中知名的定时任务框架,可以很方面的满足定时执行或周期性执行程序任务等需求,类似于Linux上的crontab,但比crontab要更加强大,该框架不仅可以添加、删除定时任务,还提供多种持久化任务的功能。
APScheduler弱分布式的框架,因为每个任务对象都存储在当前节点中,只能通过人肉的形式实现分布式,如利用Redis来做。
第一次接触APScheduler会发它有很多概念,我当年第一次接触时就是因为概念太多,直接用crontab多舒服,但现在公司项目很多都基于APScheduler实现,所以来简单扒一扒的它的源码。
前置概念
用最简单的语言提示一下APScheduler中的关键概念。
- Job: 任务对象,就是你要执行的任务
- JobStores: 任务存储方式,默认是存储在内存中,还可以支持redis、mongodb等
- Executor: 执行器,就是执行任务的东西
- Trigger: 触发器,到达某个条件触发相应的调用逻辑
- Scheduler: 调度器,将上面几个部分连接起来的东西
APScheduler提供多个Scheduler,不同Scheduler适用于不同的情景,目前我最常见的就是BackgroundScheduler后台调度器,该调度器适合要求在后台运行程序的调度。
还有多种其他调度器:
BlockingScheduler:适合于只在进程中运行单个任务的情况,通常在调度器是你唯一要运行的东西时使用。
AsyncIOScheduler:适合于使用 asyncio 框架的情况
GeventScheduler: 适合于使用 gevent 框架的情况
TornadoScheduler: 适合于使用 Tornado 框架的应用
TwistedScheduler: 适合使用 Twisted 框架的应用
QtScheduler: 适合使用 QT 的情况
本文只剖析 BackgroundScheduler 相关的逻辑,先简单看看官方example,然后以此为入口逐层剖析。
剖析BackgroundScheduler
官方example代码如下
[Python] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
|
from datetime import datetime
import time
import os
from apscheduler.schedulers.background import BackgroundScheduler
def tick():
print ( 'Tick! The time is: %s' % datetime.now())
if __name__ = = '__main__' :
scheduler = BackgroundScheduler()
scheduler.add_job(tick, 'interval' , seconds = 3 ) # 添加一个任务,3秒后运行
scheduler.start()
print ( 'Press Ctrl+{0} to exit' . format ( 'Break' if os.name = = 'nt' else 'C' ))
try :
# 这是在这里模拟应用程序活动(使主线程保持活动状态)。
while True :
time.sleep( 2 )
except (KeyboardInterrupt, SystemExit):
# 关闭调度器
scheduler.shutdown()
|
上述代码非常简单,先通过BackgroundScheduler方法实例化一个调度器,然后调用add_job方法,将需要执行的任务添加到JobStores中,默认就是存到内存中,更具体点,就是存到一个dict中,最后通过start方法启动调度器,APScheduler就会每隔3秒,触发名为interval的触发器,从而让调度器调度默认的执行器执行tick方法中的逻辑。
当程序全部执行完后,调用shutdown方法关闭调度器。
BackgroundScheduler其实是基于线程形式构成的,而线程就有守护线程的概念,如果启动了守护线程模式,调度器不一定要关闭。
先看一下BackgroundScheduler类的源码。
[Python] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
# apscheduler/schedulers/background.py
class BackgroundScheduler(BlockingScheduler):
|