详解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函数的5种参数详解
Feb 24 Python
python实现的二叉树定义与遍历算法实例
Jun 30 Python
python中列表和元组的区别
Dec 18 Python
Python序列循环移位的3种方法推荐
Apr 09 Python
django 开发忘记密码通过邮箱找回功能示例
Apr 17 Python
PyQt5每天必学之切换按钮
Aug 20 Python
PHP实现发送和接收JSON请求
Jun 07 Python
解决Python下json.loads()中文字符出错的问题
Dec 19 Python
Django Form and ModelForm的区别与使用
Dec 06 Python
pytorch 自定义卷积核进行卷积操作方式
Dec 30 Python
利用python爬取有道词典的方法
Dec 08 Python
python基础之//、/与%的区别详解
Jun 10 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
PHP 截取字符串 分别适合GB2312和UTF8编码情况
2009/02/12 PHP
PHP mb_convert_encoding文字编码的转换函数介绍
2011/11/10 PHP
php制作unicode解码工具(unicode编码转换器)代码分享
2013/12/24 PHP
PHP入门教程之图像处理技巧分析
2016/09/11 PHP
Yii2框架BootStrap样式的深入理解
2016/11/07 PHP
PHP保存Base64图片base64_decode的问题整理
2019/11/04 PHP
JS获取页面窗口大小的代码解读
2011/12/01 Javascript
JavaScript实现的图像模糊算法代码分享
2014/04/22 Javascript
jquery map方法使用示例
2014/04/23 Javascript
jQuery+PHP实现动态数字展示特效
2015/03/14 Javascript
完美实现js选项卡切换效果(二)
2017/03/08 Javascript
JS实现颜色的10进制转化成rgba格式的方法
2017/09/04 Javascript
JavaScript实现随机点名程序
2020/03/25 Javascript
js模拟实现百度搜索
2020/06/28 Javascript
element el-table表格的二次封装实现(附表格高度自适应)
2021/01/19 Javascript
[50:50]完美世界DOTA2联赛PWL S3 Galaxy Racer vs Phoenix 第一场 12.10
2020/12/13 DOTA
本地文件上传到七牛云服务器示例(七牛云存储)
2014/01/11 Python
跟老齐学Python之玩转字符串(2)更新篇
2014/09/28 Python
使用简单工厂模式来进行Python的设计模式编程
2016/03/01 Python
python实现闹钟定时播放音乐功能
2018/01/25 Python
python 中if else 语句的作用及示例代码
2018/03/05 Python
kaggle+mnist实现手写字体识别
2018/07/26 Python
Python使用googletrans报错的解决方法
2018/09/25 Python
python的reverse函数翻转结果为None的问题
2020/05/11 Python
Win 10下Anaconda虚拟环境的教程
2020/05/18 Python
HTML5实现页面切换激活的PageVisibility API使用初探
2016/05/13 HTML / CSS
应届毕业生如何写求职信
2014/02/16 职场文书
厂办主管岗位职责范本
2014/02/28 职场文书
交警作风整顿剖析材料
2014/10/11 职场文书
成本会计岗位职责
2015/02/03 职场文书
幼儿园国庆节活动总结
2015/03/23 职场文书
结婚仪式主持词
2015/06/29 职场文书
原来实习报告是这样写的呀!
2019/07/03 职场文书
阿里云Nginx配置https实现域名访问项目(图文教程)
2021/03/31 Servers
浅谈Redis位图(Bitmap)及Redis二进制中的问题
2021/07/15 Redis
基于angular实现树形二级表格
2021/10/16 Javascript