Python APScheduler 任务调度利器

官网文档:https://apscheduler.readthedocs.io/en/v3.3.0/index.html
GitHub:https://github.com/agronholm/apscheduler
安装:pip install apscheduler

调度模式

内置了三种调度模式:

  • Cron 风格
  • 间隔性(Interval-based)执行
  • 仅在某个时间执行一次

实例

from datetime import datetime
from apscheduler.schedulers.blocking import BlockingScheduler


def cronJob():
    nowtime = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    print(nowtime + ", cronJob")


def intervalJob():
    nowtime = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    print(nowtime + ", intervalJob")


# 带参数
def dateJob(text):
    print(text)


scheduler = BlockingScheduler()
scheduler.add_job(cronJob, 'cron', hour='10', minute='10')  # 每天10点10分执行
scheduler.add_job(intervalJob, 'interval', minutes=1)  # 每一分钟执行一次
scheduler.add_job(dateJob, 'date', run_date=datetime(2019, 1, 25, 16, 47, 0), args=['text'])  # 指定时间执行,也可以是 from datetime import date 类型
scheduler.start()

date

仅在某个时间执行一次

scheduler.add_job(dateJob, 'date', run_date=date(2009, 11, 6), args=['text'])
scheduler.add_job(dateJob, 'date', run_date=datetime(2019, 1, 25, 16, 47, 0), args=['text'])
scheduler.add_job(dateJob, args=['text'])  # 立即执行,'date', run_date=datetime.now(),是默认的

interval

间隔性(Interval-based)执行

按指定的时间间隔触发,如果指定则从 start_date 开始,否则为 datetime.now()+ interval。

参数:

  • weeks (int) – number of weeks to wait
  • days (int) – number of days to wait
  • hours (int) – number of hours to wait
  • minutes (int) – number of minutes to wait
  • seconds (int) – number of seconds to wait
  • start_date (datetime|str) – starting point for the interval calculation
  • end_date (datetime|str) – latest possible date/time to trigger on
  • timezone (datetime.tzinfo|str) – time zone to use for the date/time calculations
scheduler.add_job(intervalJob, 'interval', hours=2, start_date='2019-01-10 09:30:00', end_date='2019-06-15 11:00:00)

interval 设置立刻执行

scheduler.add_job(intervalJob, 'interval', hours=2, next_run_time=datetime.datetime.now())

使用装饰器

from apscheduler.scheduler import BlockingScheduler

@scheduler.scheduled_job('interval', id='my_job_id', hours=2)
def job_function():
    print("Hello World")

cron

当前时间与所有指定的时间约束匹配时触发,类似于 UNIX cron 调度程序的工作方式。与 crontab 表达式不同,您可以省略不需要的字段(默认为 *)。

参数:

  • year (int|str) – 4-digit year
  • month (int|str) – month (1-12)
  • day (int|str) – day of the (1-31)
  • week (int|str) – ISO week (1-53)
  • day_of_week (int|str) – number or name of weekday (0-6 or mon,tue,wed,thu,fri,sat,sun)
  • hour (int|str) – hour (0-23)
  • minute (int|str) – minute (0-59)
  • second (int|str) – second (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)
表达式 字段 说明
* 任意 任意值
*/a 任意 从最小值开始,触发每个值
a-b 任意 触发a-b范围内的任何值(必须小于b)
a-b/c 任意 触发a-b范围内的每个c值
xth y day 在该月内的工作日y的第x次出现时触发
last x day 在工作日x的最后一次出现在月内
last day 在这个月的最后一天
x,y,z 任意 触发任何匹配的表达式;可以组合任意数量的任何上述表达式
# 在6-8,11-12月的第三个星期五的 00:00, 01:00, 02:00, 03:00 运行
scheduler.add_job(job_function, 'cron', month='6-8,11-12', day='3rd fri', hour='0-3')
# 周一至周五上午5:30 至 2014-05-30 00:00:00
sched.add_job(job_function, 'cron', day_of_week='mon-fri', hour=5, minute=30, end_date='2014-05-30')

job

添加jobs

  • 调用 scheduler.add_job() 方法,会返回 apscheduler.job.Job 实例(可用于job修改、移除等)
  • 使用装饰器scheduled_job()

作业存储注意事项

除了 Memory 方式不需要序列化之外(一个例外是使用 ProcessPoolExecutor),其余都需要作业函数参数可序列化。

如果需要存储作业,而且每次启动时你的应用都会重新添加一遍作业,那么请在添加 job时指定一个唯一的 ID,以及指定 replace_existing=True,否则每次启动应用都会添加一次 job 的副本。

移除job

  1. scheduler.remove_job(job_id, jobstore=None)
  2. 调用 job 实例的 remove() 方法

注意:如果任务已经调度完毕,并且之后也不会再被执行的情况下,会被自动移除。

job = scheduler.add_job(myfunc, 'interval', minutes=2)
job.remove()

scheduler.add_job(myfunc, 'interval', minutes=2, id='my_job_id')
scheduler.remove_job('my_job_id')

暂停和恢复 job

apscheduler.job.Job.pause()
apscheduler.schedulers.base.BaseScheduler.pause_job()

apscheduler.job.Job.resume()
apscheduler.schedulers.base.BaseScheduler.resume_job()

获取 jobs 列表

apscheduler.get_jobs()

修改 job

可以通过 apscheduler.job.Job.modify() or apscheduler.modify_job() 修改除了 id 之外的 job 属性。

job.modify(max_instances=6, name='Alternate name')

如果你想修改 job 的调度器,你可以使用 apscheduler.job.Job.reschedule() or reschedule_job()

scheduler.reschedule_job('my_job_id', trigger='cron', minute='*/5')

interval,限制同一个 job 实例的并发执行数

默认情况下同一个 job,只允许一个 job 实例运行。这在某个 job 在下次运行时间到达之后仍未执行完毕时,能达到控制的目的。你也可以该变这一行为,在你调用 add_job 时可以传递 max_instances=5 来运行同时运行同一个 job 的 5 个 job 实例。

cron 模式,不受影响。

job 错过执行时间与 job 合并

一个 job 可能由于某些情况错过执行时间,比如上一点提到的,或者是线程池或进程池用光了,或者是当要调度 job 时,突然 down 机了等。

这时可以通过设置 job 的 misfire_grace_time 选项来指示之后尝试执行的次数。

当然如果这不符合你的期望,你可以合并所有错过时间的 job 到一个 job 来执行,通过设定 job 的 coalesce=True

Scheduler events

可以监听调度、任务执行情况相关的事件。

支持的事件列表:https://apscheduler.readthedocs.io/en/v3.3.0/modules/events.html#module-apscheduler.events

def my_listener(event):
    if event.exception:
        print('The job crashed :(')
    else:
        print('The job worked :)')

scheduler.add_listener(my_listener, EVENT_JOB_EXECUTED | EVENT_JOB_ERROR)

https://segmentfault.com/a/1190000007739974


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 bin07280@qq.com

文章标题:Python APScheduler 任务调度利器

文章字数:1.4k

本文作者:Bin

发布时间:2019-01-26, 13:59:52

最后更新:2019-08-06, 00:07:35

原始链接:http://coolview.github.io/2019/01/26/Python/Python%20APScheduler%20%E4%BB%BB%E5%8A%A1%E8%B0%83%E5%BA%A6%E5%88%A9%E5%99%A8/

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

目录