详解Python 定时框架 Apscheduler原理及安装过程


Posted in Python onJune 14, 2019

在我们的日常工作自动化测试当中,几乎超过一半的功能都需要利用定时的任务来推动触发,例如在我们项目中有一个定时监控模块,根据自己设置的频率定时跑测试用例,定时检测是否存在线上紧急任务等等,这些都涉及到了有关定时任务的问题,很多情况下,大多数人会选择window的任务计划程序,但如果程序不在window平台下运行,就不能定时启动了;当然也可利用time模块的time.sleep()方法使程序休眠来达到定时任务的目的,但定时任务多了,代码可能看起来不太那么友好且有很大的局限性,因此,此时的 Apscheduler 框架是你的不二选择。

Apscheduler

Apscheduler基于Quartz的一个python定时任务框架,实现Quart的所有功能,相关的接口调用起来比较方便,目前其提供了基于日期、固定时间间隔以及corntab类型的任务,并且同时可进行持久化任务;同时它提供了多种不同的调用器,方便开发者根据自己的需求进行使用,也方便与数据库等第三方的外部持久化储存机制进行协同工作,非常强大。

基本原理

总的来说,主要是利用python threading Event和Lock锁来写的。scheduler在主循环(main_loop)中, 反复检查是否有需要执行的任务,完成任务的检查函数为 _process_jobs,主要有那个几个步骤:

1、 询问储存的每个 jobStore ,是否有到期要执行的任务。

详解Python 定时框架 Apscheduler原理及安装过程

2、 due_jobs 不为空,则计算这些jobs中每个job需要运行的时间点,时间一到就提交给submit作任务调度。

详解Python 定时框架 Apscheduler原理及安装过程

3、在主循环中,如果不间断地调用,而实际上没有要执行的job,这会造成资源浪费。因此在程序中,如果每次掉用 _process_jobs 后,进行了预先判断,判断下一次要执行的job(离现在最近的)还要多长时间,作为返回值告诉main_loop, 这时主循环就可以去睡一觉,等大约这么长时间后再唤醒,执行下一次 _process_jobs

安装

1、可以直接使用pip进行安装

2、源码安装

详解Python 定时框架 Apscheduler原理及安装过程

### 基础概念

在Apscheduler中主要有以下几个非常重要的概念,主要如下:

触发器(trigger):

某一个工作到来时引发的事件,包含调度的逻辑,每一个作业都有它自己的触发器,用于决定哪个作业任务会执行,除了它们初始化配置之外,其完全是无状态的。总的来说就是 一个任务应该在什么时候执行

执行器(executor):

主要是处理作业的运行,它将要执行的作业放在新的线程或者线程池中运行。执行完毕之后,再通知调度器。基于线程池的操作,可以针对不同类型的作业任务,更为高效的使用CPU的计算资源。

作业存储(job stores)

保存要调度的任务,其中除了默认的作业存储是把作业保存在内存中,其他的作业存储是将作业保存在数据库中。一个作业的数据将在保存在持久化的作业存储之前,会对作业执行序列化操作,当重新读取作业时,再执行反序列化操作。同时,调度器不能分享同一个作业存储。作业存储支持主流的存储机制:如redis,mongodb,关系型数据库,内存等等。

调度器(scheduler):

负责将上面几个组件联系在一起,一般在应用中只有一个调度器,程序开发者不会直接操作触发器、作业存储或执行器,而是利用调度器提供了处理这些合适的接口,作业存储和执行器的配置都是通过在调度器中完成的。

在我们的使用过程中,选择合适的 调度器 是根据我们的开发环境以及实际应用来决定的,根据IO模型的不同,主要有下面一些常见的调度器:

  • BlockingScheduler:适合于只在进程中运行单个任务的情况
  • BackgroundScheduler: 适合于不运行使用其他框架时,并希望在程序后台执行的情况
  • AsyncIOScheduler:适合于使用asyncio框架的情况
  • GeventScheduler: 适合于使用gevent框架的情况
  • TornadoScheduler: 适合于使用Tornado框架的应用
  • TwistedScheduler: 适合使用Twisted框架的应用
  • QtScheduler: 适合使用QT的情况

而对于 作业存储 ,如果是非持久性作业,使用默认的 MemoryStore 就行了,若是持久性任务,那么就需要根据应用环境来进行选择。

大多数情况下, 执行器 选择 ThreadPoolExecutor 就够用了,但如果涉及到比较消耗CPU的作业,就可以选择ProcessPoolExecutor* ,以充分利用多核CPU。当然也可以同时配置使用两个执行器,将进程池 ProcessPoolExecutor 调度器作为你的第二个执行器。

配置调度器

Apscheduler框架提供了许多调度器的配置方法,既可以使用配置字典,也可以直接传递配置参数给调度器使用; 同时支持先初始化调度器,添加完作业任务后,再来配置调度器等。

说了这么多,我们可以来先举个简单的例子:

详解Python 定时框架 Apscheduler原理及安装过程

上面的代码生成一个默认的调度器,默认使用名为 default 的 MemoryJobStore,以及使用默认名为 default 的 ThreadPoolExecutor ,最大线程数为10 。

下面进行一个复杂的配置,同时使用两个作业存储和两个执行器,在这个配置中,修改默认的配置参数,jobstored指的是job持久化,默认job运行在内存中,可持久化在数据库,指定为mongo的MongoDBJobStore或者是使用sqlite的SQLAlchemyJobStore,同时可指定多种jobstore。

详解Python 定时框架 Apscheduler原理及安装过程

coalesce :当由于某种原因导致某个job积攒了好几次没有实际运行(比如说系统挂了5分钟后恢复,有一个任务是每分钟跑一次的,按道理说这5分钟内本来是“计划”运行5次的,但实际没有执行),如果coalesce为True,下次这个job被submit给executor时,只会执行1次,也就是最后这次,如果为False,那么会执行5次(不一定,因为还有其他条件,看后面misfiregracetime的解释)。

max_instance :每个job在同一时刻能够运行的最大实例数,默认情况下为1个,可以指定为更大值,这样即使上个job还没运行完同一个job又被调度的话也能够再开一个线程执行。

misfire_grace_time :单位为秒,假设有这么一种情况,当某一job被调度时刚好线程池都被占满,调度器会选择将该job排队不运行,misfiregracetime参数则是在线程池有可用线程时会比对该job的应调度时间跟当前时间的差值,如果差值<misfiregracetime时,调度器会再次调度该job.反之该job的执行状态为EVENTJOBMISSED了,即错过运行.</misfire。

启动/关闭调度器

使用 start() 方法来启动调度器,其中须注意的是 BlockingScheduler 需要在初始化之后才能执行 start() ,对于其他的调度器,调用 start() 方法都会直接返回,然后可以继续执行后面的初始化操作。同时,调度器启动之后,就不能再更改它的配置了。

在默认情况下,调度器会等所有的作业任务完成后,自动关闭所有的调度器及作业存储。若在使用过程中不想等待,可以将 wait 参数选项设为 False ,则表示直接关闭:

详解Python 定时框架 Apscheduler原理及安装过程

调度器监听事件

可以给调度器添加事件监听器,调度器事件只有在某些情况下才会被触发,并且可以携带某些有用的信息。通过给 add_listener() 传递合适的 mask 参数,可以只监听几种特定的事件类型,具体类型可看源码中的 event.exception 或者 event.code 值来做识别判断。

 详解Python 定时框架 Apscheduler原理及安装过程

作业及作业存储

jobstore提供给scheduler一个序列化jobs的统一抽象,提供对scheduler中job的增删改查接口,根据存储backend的不同,分以下几种:

MemoryJobStore :没有序列化,jobs就存在内存里,增删改查也都是在内存中操作

SQLAlchemyJobStore :所有sqlalchemy支持的数据库都可以做为backend,增删改查操作转化为对应backend的sql语句

MongoDBJobStore :用mongodb作backend

RedisJobStore : 用redis作backend

Job是框架承接目前需要执行的工作和任务,我们可以在系统运行过程中进行动态的增加、修改、删除、查询等操作。

1、添加作业

上面是通过 add_job() 来添加作业,另外还有一种方式是通过修饰器 scheduled_job 来动态装饰 Job 的实际函数

详解Python 定时框架 Apscheduler原理及安装过程 

2、移除作业

详解Python 定时框架 Apscheduler原理及安装过程 

3、暂停作业

详解Python 定时框架 Apscheduler原理及安装过程

4、恢复作业

详解Python 定时框架 Apscheduler原理及安装过程

5、修改作业

详解Python 定时框架 Apscheduler原理及安装过程

6、获取Job列表

获得调度作业的列表,可以使用 get_jobs() 来完成,它会返回所有的job实例,同时也可使用 print_jobs() 来输出所有格式化的作业列表。也可以利用 get_job(任务ID) 获取指定任务的作业列表

详解Python 定时框架 Apscheduler原理及安装过程

作业运行控制

add_job() 方法的第二个参数是trigger,它管理着作业任务的调度方式,它可以被设置为 dataintervalcorn 三种类别。对于不同的设置类别,对应的参数也有所不同,具体如下:

1、corn 定时调度,即规定在某一时刻执行

详解Python 定时框架 Apscheduler原理及安装过程

详解Python 定时框架 Apscheduler原理及安装过程

使用例子:

详解Python 定时框架 Apscheduler原理及安装过程

详解Python 定时框架 Apscheduler原理及安装过程

2、interval间隔调度,即每隔多久执行一次

详解Python 定时框架 Apscheduler原理及安装过程

3、data定时调度,即设置后作业只会执行一次,是最基本的调度模式

详解Python 定时框架 Apscheduler原理及安装过程

总结

Apscheduler是一个非常强大且易用的类库,可以方便我们快速的搭建一些强大的定时任务或者定时监控类的调度系统,在实际工作中非常有用,同时其也提供了不少的扩展点。

以上所述是小编给大家介绍的Python 定时框架 Apscheduler,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

Python 相关文章推荐
python encode和decode的妙用
Sep 02 Python
给Python IDLE加上自动补全和历史功能
Nov 30 Python
在Python中使用SimpleParse模块进行解析的教程
Apr 11 Python
Python中多线程的创建及基本调用方法
Jul 08 Python
Python操作word常见方法示例【win32com与docx模块】
Jul 17 Python
详解Python装饰器
Mar 25 Python
python中yield的用法详解——最简单,最清晰的解释
Apr 04 Python
python脚本执行CMD命令并返回结果的例子
Aug 14 Python
python GUI库图形界面开发之PyQt5浏览器控件QWebEngineView详细使用方法
Feb 26 Python
Python 判断时间是否在时间区间内的实例
May 16 Python
python安装后的目录在哪里
Jun 21 Python
通过实例解析Python文件操作实现步骤
Sep 21 Python
在python tkinter中Canvas实现进度条显示的方法
Jun 14 #Python
浅谈PySpark SQL 相关知识介绍
Jun 14 #Python
python Tkinter的图片刷新实例
Jun 14 #Python
基于Python的Post请求数据爬取的方法详解
Jun 14 #Python
Appium+python自动化怎么查看程序所占端口号和IP
Jun 14 #Python
Python中py文件转换成exe可执行文件的方法
Jun 14 #Python
10 行Python 代码实现 AI 目标检测技术【推荐】
Jun 14 #Python
You might like
德劲1102收音机的打理维修案例
2021/03/02 无线电
PHP中其实也可以用方法链
2011/11/10 PHP
PHP中的Memcache详解
2014/04/05 PHP
php metaphone()函数的定义和用法
2016/05/15 PHP
Laravel第三方包报class not found的解决方法
2019/10/13 PHP
Javascript 函数中的参数使用分析
2010/03/27 Javascript
JS在TextArea光标位置插入文字并实现移动光标到文字末尾
2013/06/21 Javascript
JS window对象的top、parent、opener含义介绍
2013/12/03 Javascript
js获取某元素的class里面的css属性值代码
2014/01/16 Javascript
jquery控制display属性为none或block
2014/03/31 Javascript
JS实现鼠标经过好友列表中的好友头像时显示资料卡的效果
2014/07/02 Javascript
基于jquery实现发送文章到手机的代码
2014/12/26 Javascript
实现音乐播放器的代码(html5+css3+jquery)
2015/08/04 Javascript
jquery对象和DOM对象的任意相互转换
2016/02/21 Javascript
JavaScript实现点击文本自动定位到下拉框选中操作
2016/06/15 Javascript
WebView启动支付宝客户端支付失败的问题小结
2017/01/11 Javascript
Vuejs 用$emit与$on来进行兄弟组件之间的数据传输通信
2017/02/23 Javascript
使用OPENLAYERS3实现点选的方法
2020/09/24 Javascript
如何抽象一个Vue公共组件
2017/10/17 Javascript
JS 中使用Promise 实现红绿灯实例代码(demo)
2017/10/20 Javascript
vue.js内置组件之keep-alive组件使用
2018/07/10 Javascript
详解利用eventemitter2实现Vue组件通信
2019/11/04 Javascript
JS实现简易计算器
2020/02/14 Javascript
vue组件入门知识全梳理
2020/09/21 Javascript
[03:30]完美盛典趣味短片 CSGO2019年度名场面
2019/12/07 DOTA
python生成随机图形验证码详解
2017/11/08 Python
Python定时任务sched模块用法示例
2018/07/16 Python
Python递归及尾递归优化操作实例分析
2020/02/01 Python
举例详解CSS3中的Transition
2015/07/15 HTML / CSS
俄罗斯最大的消费电子连锁零售商:Mvideo
2017/06/25 全球购物
英国的屈臣氏:Boots博姿
2017/12/23 全球购物
教师辞职报告范文
2014/01/20 职场文书
七一党日活动总结
2014/07/08 职场文书
晚会开场白和结束语
2015/05/29 职场文书
MySQL的Query Cache图文详解
2021/07/01 MySQL
Win11如何修改dns?Win11修改dns图文教程
2022/01/18 数码科技