APScheduler学习

说明

APScheduler是一个 Python 定时任务框架,使用起来十分方便。提供了基于日期、固定时间间隔以及 crontab 类型的任务,并且可以持久化任务、并以 daemon 方式运行应用。

使用 APScheduler 需要安装

安装:

1 pip install apscheduler

首先来看一个周一到周五每天早上6点半喊我起床的例子:

1 from apscheduler.schedulers.blocking import BlockingScheduler
2 from datetime import datetime
3 # 输出时间
4 def job():
5     print(datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
6 # BlockingScheduler
7 scheduler = BlockingScheduler()
8 scheduler.add_job(job, ‘cron‘, day_of_week=‘1-5‘, hour=6, minute=30)
9 scheduler.start()

代码中的 BlockingScheduler 是什么呢?

BlockingScheduler是APScheduler中的调度器,APScheduler 中有两种常用的调度器,BlockingScheduler 和 BackgroundScheduler,当调度器是应用中唯一要运行的任务时,使用 BlockingSchedule,如果希望调度器在后台执行,使用 BackgroundScheduler。

APScheduler四个组件

APScheduler 四个组件分别为:触发器(trigger),作业存储(job store),执行器(executor),调度器(scheduler)。

触发器(trigger)

包含调度逻辑,每一个作业有它自己的触发器,用于决定接下来哪一个作业会运行。除了他们自己初始配置意外,触发器完全是无状态的

APScheduler 有三种内建的 trigger:

  • date: 特定的时间点触发
  • interval: 固定时间间隔触发
  • cron: 在特定时间周期性地触发

作业存储(job store)

存储被调度的作业,默认的作业存储是简单地把作业保存在内存中,其他的作业存储是将作业保存在数据库中。一个作业的数据讲在保存在持久化作业存储时被序列化,并在加载时被反序列化。调度器不能分享同一个作业存储。

APScheduler 默认使用 MemoryJobStore,可以修改使用 DB 存储方案

执行器(executor)

处理作业的运行,他们通常通过在作业中提交制定的可调用对象到一个线程或者进城池来进行。当作业完成时,执行器将会通知调度器。

最常用的 executor 有两种:

  • ProcessPoolExecutor
  • ThreadPoolExecutor

调度器(scheduler)

通常在应用中只有一个调度器,应用的开发者通常不会直接处理作业存储、调度器和触发器,相反,调度器提供了处理这些的合适的接口。配置作业存储和执行器可以在调度器中完成,例如添加、修改和移除作业。

配置调度器

APScheduler提供了许多不同的方式来配置调度器,你可以使用一个配置字典或者作为参数关键字的方式传入。你也可以先创建调度器,再配置和添加作业,这样你可以在不同的环境中得到更大的灵活性。

下面来看一个简单的 BlockingScheduler 例子

 1 from apscheduler.schedulers.blocking import BlockingScheduler
 2 from datetime import datetime
 3
 4
 5 def job():
 6     print(datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
 7 # 定义BlockingScheduler
 8 sched = BlockingScheduler()
 9 sched.add_job(job, ‘interval‘, seconds=5)
10 sched.start()

上述代码创建了一个 BlockingScheduler,并使用默认内存存储和默认执行器。(默认选项分别是 MemoryJobStore 和 ThreadPoolExecutor,其中线程池的最大线程数为10)。配置完成后使用 start() 方法来启动。

如果想要显式设置 job store(使用mongo存储)和 executor 可以这样写:

 1 from datetime import datetime
 2 from pymongo import MongoClient
 3 from apscheduler.schedulers.blocking import BlockingScheduler
 4 from apscheduler.jobstores.memory import MemoryJobStore
 5 from apscheduler.jobstores.mongodb import MongoDBJobStore
 6 from apscheduler.executors.pool import ThreadPoolExecutor, ProcessPoolExecutor
 7 # MongoDB 参数
 8 host = ‘127.0.0.1‘
 9 port = 27017
10 client = MongoClient(host, port)
11 # 输出时间
12 def job():
13     print(datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
14 # 存储方式
15 jobstores = {
16     ‘mongo‘: MongoDBJobStore(collection=‘job‘, database=‘test‘, client=client),
17     ‘default‘: MemoryJobStore()
18 }
19 executors = {
20     ‘default‘: ThreadPoolExecutor(10),
21     ‘processpool‘: ProcessPoolExecutor(3)
22 }
23 job_defaults = {
24     ‘coalesce‘: False,
25     ‘max_instances‘: 3
26 }
27 scheduler = BlockingScheduler(jobstores=jobstores, executors=executors, job_defaults=job_defaults)
28 scheduler.add_job(job, ‘interval‘, seconds=5, jobstore=‘mongo‘)
29 scheduler.start()

在运行程序5秒后,第一次输出时间。

在 MongoDB 中可以看到 job 的状态

对 job 的操作

添加 job

添加job有两种方式:

  1. add_job()
  2. scheduled_job()

第二种方法只适用于应用运行期间不会改变的 job,而第一种方法返回一个apscheduler.job.Job 的实例,可以用来改变或者移除 job。

1 from apscheduler.schedulers.blocking import BlockingScheduler
2 sched = BlockingScheduler()
3 # 装饰器
4 @sched.scheduled_job(‘interval‘, id=‘my_job_id‘, seconds=5)
5 def job_function():
6     print("Hello World")
7 # 开始
8 sched.start()

@sched.scheduled_job() 是 Python 的装饰器。

移除 job

移除 job 也有两种方法:

  1. remove_job()
  2. job.remove() 

remove_job 使用 jobID 移除

job.remove() 使用 add_job() 返回的实例

1 job = scheduler.add_job(myfunc, ‘interval‘, minutes=2)
2 job.remove()
3 # id
4 scheduler.add_job(myfunc, ‘interval‘, minutes=2, id=‘my_job_id‘)
5 scheduler.remove_job(‘my_job_id‘)

暂停和恢复 job

暂停一个 job:

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

恢复一个 job:

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

希望你还记得 apscheduler.job.Job 是 add_job() 返回的实例

获取 job 列表

获得可调度 job 列表,可以使用get_jobs() 来完成,它会返回所有的 job 实例。

也可以使用print_jobs() 来输出所有格式化的 job 列表

修改 job

除了 jobID 之外 job 的所有属性都可以修改,使用 apscheduler.job.Job.modify() 或者 modify_job() 修改一个 job 的属性

1 job.modify(max_instances=6, name=‘Alternate name‘)
2 modify_job(‘my_job_id‘, trigger=‘cron‘, minute=‘*/5‘)

关闭 job

默认情况下调度器会等待所有的 job 完成后,关闭所有的调度器和作业存储。将 wait 选项设置为 False 可以立即关闭。

1 scheduler.shutdown()
2 scheduler.shutdown(wait=False)

scheduler 事件

scheduler 可以添加事件监听器,并在特殊的时间触发。

1 def my_listener(event):
2     if event.exception:
3         print(‘The job crashed :(‘)
4     else:
5         print(‘The job worked :)‘)
6 # 添加监听器
7 scheduler.add_listener(my_listener, EVENT_JOB_EXECUTED | EVENT_JOB_ERROR)

trigger 规则

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
 1 from datetime import date
 2 from apscheduler.schedulers.blocking import BlockingScheduler
 3 sched = BlockingScheduler()
 4 def my_job(text):
 5     print(text)
 6 # The job will be executed on November 6th, 2009
 7 sched.add_job(my_job, ‘date‘, run_date=date(2009, 11, 6), args=[‘text‘])
 8 sched.add_job(my_job, ‘date‘, run_date=datetime(2009, 11, 6, 16, 30, 5), args=[‘text‘])
 9 sched.add_job(my_job, ‘date‘, run_date=‘2009-11-06 16:30:05‘, args=[‘text‘])
10 # The ‘date‘ trigger and datetime.now() as run_date are implicit
11 sched.add_job(my_job, args=[‘text‘])
12 sched.start()

cron

  • 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)

中文释义:


参数

说明

(int|str)

表示参数既可以是int类型,也可以是str类型

(datetime | str)

表示参数既可以是datetime类型,也可以是str类型

year(int or str)

年,4位数字

month(int or str)

月(范围1-12)

day(int or str)

日(范围1-31)

week(int or str)

周(范围1-53)

day_of_week(int or str)

周内第几天或者星期几(范围0-6或者mon,tue,wed,thu,fri,stat,sun)

hour(int or str)

时(0-23)

minute(int or str)

分(0-59)

second(int or str)

秒(0-59)

start_date(datetime or str)

最早开始日期(含)

end_date(datetime or str)

最晚结束日期(含)
timezone(datetime.tzinfo or   str) 指定时区

表达式:

示例:

 1 from apscheduler.schedulers.blocking import BlockingScheduler
 2
 3
 4 def job_function():
 5     print("Hello World")
 6 # BlockingScheduler
 7 sched = BlockingScheduler()
 8 # Schedules job_function to be run on the third Friday
 9 # of June, July, August, November and December at 00:00, 01:00, 02:00 and 03:00
10 sched.add_job(job_function, ‘cron‘, month=‘6-8,11-12‘, day=‘3rd fri‘, hour=‘0-3‘)
11 # Runs from Monday to Friday at 5:30 (am) until 2014-05-30 00:00:00
12 sched.add_job(job_function, ‘cron‘, day_of_week=‘mon-fri‘, hour=5, minute=30, end_date=‘2014-05-30‘)
13 sched.start()

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

示例:

 1 from datetime import datetime
 2 from apscheduler.schedulers.blocking import BlockingScheduler
 3
 4
 5 def job_function():
 6     print("Hello World")
 7 # BlockingScheduler
 8 sched = BlockingScheduler()
 9 # Schedule job_function to be called every two hours
10 sched.add_job(job_function, ‘interval‘, hours=2)
11 # The same as before, but starts on 2010-10-10 at 9:30 and stops on 2014-06-15 at 11:00
12 sched.add_job(job_function, ‘interval‘, hours=2, start_date=‘2010-10-10 09:30:00‘, end_date=‘2014-06-15 11:00:00‘)
13 sched.start()

踩坑记录:

1、cron编写场景为每周五上午十点执行一次时,day_of_week字段为4,即当前星期数-1,也可以写成‘fri‘

文章来源:

https://www.cnblogs.com/fengff/p/11011000.html

http://www.chenxm.cc/article/829.html

原文地址:https://www.cnblogs.com/longweiqiang/p/11993929.html

时间: 2024-10-13 14:54:04

APScheduler学习的相关文章

定时任务框架APScheduler学习详解

APScheduler简介 在平常的工作中几乎有一半的功能模块都需要定时任务来推动,例如项目中有一个定时统计程序,定时爬出网站的URL程序,定时检测钓鱼网站的程序等等,都涉及到了关于定时任务的问题,第一时间想到的是利用time模块的time.sleep()方法使程序休眠来达到定时任务的目的,虽然这样也可以,但是总觉得不是那么的专业,^_^所以就找到了python的定时任务模块APScheduler: APScheduler基于Quartz的一个Python定时任务框架,实现了Quartz的所有功

Vue.js学习笔记:属性绑定 v-bind

v-bind  主要用于属性绑定,Vue官方提供了一个简写方式 :bind,例如: <!-- 完整语法 --> <a v-bind:href="url"></a> <!-- 缩写 --> <a :href="url"></a> 绑定HTML Class 一.对象语法: 我们可以给v-bind:class 一个对象,以动态地切换class.注意:v-bind:class指令可以与普通的class特

Java多线程学习(吐血超详细总结)

林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 目录(?)[-] 一扩展javalangThread类 二实现javalangRunnable接口 三Thread和Runnable的区别 四线程状态转换 五线程调度 六常用函数说明 使用方式 为什么要用join方法 七常见线程名词解释 八线程同步 九线程数据传递 本文主要讲了java中多线程的使用方法.线程同步.线程数据传递.线程状态及相应的一些线程函数用法.概述等. 首先讲一下进程和线程

微信小程序学习总结(2)------- 之for循环,绑定点击事件

最近公司有小程序的项目,本人有幸参与其中,一个项目做下来感觉受益匪浅,与大家做下分享,欢迎沟通交流互相学习. 先说一下此次项目本人体会较深的几个关键点:微信地图.用户静默授权.用户弹窗授权.微信充值等等. 言归正传,今天分享我遇到的关于wx:for循环绑定数据的一个tips:  1. 想必大家的都知道wx:for,如下就不用我啰嗦了: <view class="myNew" wx:for="{{list}}">{{item.title}}<view

【安全牛学习笔记】

弱点扫描 ╋━━━━━━━━━━━━━━━━━━━━╋ ┃发现弱点                                ┃ ┃发现漏洞                                ┃ ┃  基于端口五福扫描结果版本信息(速度慢)┃ ┃  搜索已公开的漏洞数据库(数量大)      ┃ ┃  使用弱点扫描器实现漏洞管理            ┃ ╋━━━━━━━━━━━━━━━━━━━━╋ [email protected]:~# searchsploit Usage:

winform学习日志(二十三)---------------socket(TCP)发送文件

一:由于在上一个随笔的基础之上拓展的所以直接上代码,客户端: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Net.Sockets; using Sys

零基础的人该怎么学习JAVA

对于JAVA有所兴趣但又是零基础的人,该如何学习JAVA呢?对于想要学习开发技术的学子来说找到一个合适自己的培训机构是非常难的事情,在选择的过程中总是 因为这样或那样的问题让你犹豫不决,阻碍你前进的步伐,今天就让小编为您推荐培训机构新起之秀--乐橙谷Java培训机构,助力你成就好未来. 选择java培训就到乐橙谷 北京有什么好的Java培训机构?来乐橙谷北京学Java,零基础走起,乐橙谷Java基础班授课老师经验非常丰富,课程内容安排合理,适合于有一点点Java基础甚至一点都不会Java的同学学

最全解析如何正确学习JavaScript指南,必看!

划重点 鉴于时不时,有同学私信问我:怎么学前端的问题.这里统一回复一下,如下次再遇到问我此问题同学,就直接把本文链接地址发给你了. "前端怎么学"应该因人而异,别人的方法未必适合自己.就说说我的学习方法吧:我把大部分时间放在学习js上了.因为这个js的学习曲线,先平后陡.项目实践和练习啥的,我不说了,主要说下工作之外的时间利用问题.我是怎么学的呢,看书,分析源码.个人这几天统计了一下,前端书籍目前看了50多本吧,大部分都是js的.市面上的书基本,差不多都看过. 第一个问题:看书有啥好处

轻松学习C语言编程的秘诀:总结+灵感

目前在准备一套C语言的学习教程,所以我这里就以C语言编程的学习来讲.注意,讲的是"轻松学习",那种不注重方法,拼命玩命的方式也有其效果,但不是我提倡的.我讲究的是在方式方法对头.适合你.减轻你学习负担和心里压力的前提下,才适当的抓紧时间. 因此,探索一种很好的学习方法就是我所研究的主要内容. 众所周知,学习C语言并非易事,要学好它更是难上加难.这和你期末考试背会几个题目的答案考上满分没多大关系,也就是说你考试满分也说明不了你学好.学精通了C语言.那么怎么才算学精通C语言?闭着眼睛对自己