Python任务调度利器之APScheduler详解


Posted in Python onApril 02, 2020

Python任务调度利器之APScheduler详解 

任务调度应用场景

所谓的任务调度是指安排任务的执行计划,即何时执行,怎么执行等。在现实项目中经常出现它们的身影;特别是数据类项目,比如实时统计每5分钟网站的访问量,就需要每5分钟定时从日志数据分析访问量。

总结下任务调度应用场景:

  •  离线作业调度:按时间粒度执行某项任务
  •  共享缓存更新:定时刷新缓存,如redis缓存;不同进程间的共享数据

任务调度工具

  •  linux的crontab, 支持按照分钟/小时/天/月/周粒度,执行任务
  •  java的Quartz
  •  windows的任务计划

本文介绍的是python中的任务调度库,APScheduler(advance python scheduler)。如果你了解Quartz的话,可以看出APScheduler是Quartz的python实现;APScheduler提供了基于时间,固定时间点和crontab方式的任务调用方案, 可以当作一个跨平台的调度工具来使用。

APScheduler

组件介绍

APScheduler由5个部分组成:触发器、调度器、任务存储器、执行器和任务事件。

  •  任务job:任务id和任务执行func
  •  触发器triggers:确定任务何时开始执行
  •  任务存储器job stores: 保存任务的状态
  •  执行器executors:确定任务怎么执行
  •  任务事件event:监控任务执行异常情况
  •  调度器schedulers:串联任务的整个生命周期,添加编辑任务到任务存储器,在任务的执行时间到来时,把任务交给执行器执行返回结果;同时发出事件监听,监控任务事件 。

Python任务调度利器之APScheduler详解 

安装

pip install apscheduler

简单例子

from apscheduler.schedulers.background import BackgroundScheduler 
from apscheduler.executors.pool import ThreadPoolExecutor, ProcessPoolExecutor 
from apscheduler.jobstores.sqlalchemy import SQLAlchemyJobStore 
from apscheduler.events import EVENT_JOB_EXECUTED, EVENT_JOB_ERROR 
import logging 
import datetime 
# 任务执行函数 
def job_func(job_id): 
 print('job %s is runed at %s' % (job_id, datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'))) 
# 事件监听 
def job_exception_listener(event): 
 if event.exception: 
 # todo:异常处理, 告警等 
 print('The job crashed :(') 
 else: 
 print('The job worked :)') 
# 日志 
logging.basicConfig() 
logging.getLogger('apscheduler').setLevel(logging.DEBUG) 
# 定义一个后台任务非阻塞调度器 
scheduler = BackgroundScheduler() 
# 添加一个任务到内存中 
# 触发器:trigger='interval' seconds=10 每10s触发执行一次 
# 执行器:executor='default' 线程执行 
# 任务存储器:jobstore='default' 默认内存存储 
# 最大并发数:max_instances 
scheduler.add_job(job_func, trigger='interval', args=[1], id='1', name='a test job', max_instances=10, jobstore='default', executor='default', seconds=10) 
# 设置任务监听 
scheduler.add_listener(job_exception_listener, EVENT_JOB_EXECUTED | EVENT_JOB_ERROR) 
# 启动调度器 
scheduler.start()

运行情况:

job 1 is runed at 2020-03-21 20:00:38 
The job worked :) 
job 1 is runed at 2020-03-21 20:00:48 
The job worked :) 
job 1 is runed at 2020-03-21 20:00:58 
The job worked :)

触发器

触发器决定何时执行任务,APScheduler支持的触发器有3种

 trigger='interval':按固定时间周期执行,支持weeks,days,hours,minutes, seconds, 还可指定时间范围  

sched.add_job(job_function, 'interval', hours=2, start_date='2010-10-10 09:30:00', end_date='2014-06-15 11:00:00') 

 trigger='date': 固定时间,执行一次  

sched.add_job(my_job, 'date', run_date=datetime(2009, 11, 6, 16, 30, 5), args=['text']) 

  trigger='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)

  例子          

# 星期一到星期五,5点30执行任务job_function,直到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') 
  # 按照crontab格式执行, 格式为:分钟 小时 天 月 周,*表示所有 
  # 5月到8月的1号到15号,0点0分执行任务job_function 
  sched.add_job(job_function, CronTrigger.from_crontab('0 0 1-15 may-aug *'))

执行器

执行器决定如何执行任务;APScheduler支持4种不同执行器,常用的有pool(线程/进程)和gevent(io多路复用,支持高并发),默认为pool中线程池, 不同的执行器可以在调度器的配置中进行配置(见调度器)

  •  apscheduler.executors.asyncio:同步io,阻塞
  •  apscheduler.executors.gevent:io多路复用,非阻塞
  •  apscheduler.executors.pool: 线程ThreadPoolExecutor和进程ProcessPoolExecutor
  •  apscheduler.executors.twisted:基于事件驱动

任务存储器

任务存储器决定任务的保存方式, 默认存储在内存中(MemoryJobStore),重启后就没有了。APScheduler支持的任务存储器有:

  •  apscheduler.jobstores.memory:内存
  •  apscheduler.jobstores.mongodb:存储在mongodb
  •  apscheduler.jobstores.redis:存储在redis
  •  apscheduler.jobstores.rethinkdb:存储在rethinkdb
  •  apscheduler.jobstores.sqlalchemy:支持sqlalchemy的数据库如mysql,sqlite等
  •  apscheduler.jobstores.zookeeper:zookeeper

不同的任务存储器可以在调度器的配置中进行配置(见调度器)

调度器

APScheduler支持的调度器方式如下,比较常用的为BlockingScheduler和BackgroundScheduler

  •  BlockingScheduler:适用于调度程序是进程中唯一运行的进程,调用start函数会阻塞当前线程,不能立即返回。
  •  BackgroundScheduler:适用于调度程序在应用程序的后台运行,调用start后主线程不会阻塞。
  •  AsyncIOScheduler:适用于使用了asyncio模块的应用程序。
  •  GeventScheduler:适用于使用gevent模块的应用程序。
  •  TwistedScheduler:适用于构建Twisted的应用程序。
  •  QtScheduler:适用于构建Qt的应用程序。

从前面的例子,我们可以看到,调度器可以操作任务(并为任务指定触发器、任务存储器和执行器)和监控任务。

scheduler.add_job(job_func, trigger='interval', args=[1], id='1', name='a test job', max_instances=10, jobstore='default', executor='default', seconds=10)

我们来详细看下各个部分

 调度器配置:在add_job我们看到jobstore和executor都是default,APScheduler在定义调度器时可以指定不同的任务存储和执行器,以及初始的参数  

from pytz import utc 
 from apscheduler.schedulers.background import BackgroundScheduler 
 from apscheduler.jobstores.mongodb import MongoDBJobStore 
 from apscheduler.jobstores.sqlalchemy import SQLAlchemyJobStore 
 from apscheduler.executors.pool import ThreadPoolExecutor, ProcessPoolExecutor 
 # 通过dict方式执行不同的jobstores、executors和默认的参数 
 jobstores = { 
 'mongo': MongoDBJobStore(), 
 'default': SQLAlchemyJobStore(url='sqlite:///jobs.sqlite') 
 } 
 executors = { 
 'default': ThreadPoolExecutor(20), 
 'processpool': ProcessPoolExecutor(5) 
 } 
 job_defaults = { 
 'coalesce': False, 
 'max_instances': 3 
 } 
 # 定义调度器 
 scheduler = BackgroundScheduler(jobstoresjobstores=jobstores, executorsexecutors=executors, job_defaultsjob_defaults=job_defaults, timezone=utc) 
 def job_func(job_id): 
 print('job %s is runed at %s' % (job_id, datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'))) 
 # 添加任务 
 scheduler.add_job(job_func, trigger='interval', args=[1], id='1', name='a test job', jobstore='default', executor='processpool', seconds=10) 
 # 启动调度器 
 scheduler.start()

 操作任务:调度器可以增加,删除,暂停,恢复和修改任务。需要注意的是这里的操作只是对未执行的任务起作用,已经执行和正在执行的任务不受这些操作的影响。

  add_job    

scheduler.add_job(job_func, trigger='interval', args=[1], id='1', name='a test job', max_instances=10, jobstore='default', executor='default', seconds=10)

  remove_job: 通过任务唯一的id,删除的时候对应的任务存储器里记录也会删除

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

  Pausing and resuming jobs:暂停和重启任务      

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

  Modifying jobs:修改任务的配置      

job = scheduler.add_job(myfunc, 'interval', minutes=2, id='my_job_id', max_instances=10) 
 # 修改任务的属性 
 job.modify(max_instances=6, name='Alternate name') 
 # 修改任务的触发器 
 scheduler.reschedule_job('my_job_id', trigger='cron', minute='*/5')

监控任务事件类型,比较常用的类型有:

  •   EVENT_JOB_ERROR: 表示任务在执行过程的出现异常触发
  •   EVENT_JOB_EXECUTED:任务执行成功时
  •   EVENT_JOB_MAX_INSTANCES:调度器上执行的任务超过配置的参数时      

scheduler.add_listener(job_exception_listener, EVENT_JOB_EXECUTED | EVENT_JOB_ERROR)   

总结

到此这篇关于Python任务调度利器之APScheduler详解的文章就介绍到这了,更多相关python任务调度 APScheduler内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
重命名批处理python脚本
Apr 05 Python
python删除列表内容
Aug 04 Python
python实现将内容分行输出
Nov 05 Python
Python 的内置字符串方法小结
Mar 15 Python
Windows中使用wxPython和py2exe开发Python的GUI程序的实例教程
Jul 11 Python
Python中修改字符串的四种方法
Nov 02 Python
python中的协程深入理解
Jun 10 Python
如何使用python代码操作git代码
Feb 29 Python
python 安装impala包步骤
Mar 28 Python
使用PyCharm官方中文语言包汉化PyCharm
Nov 18 Python
Django-celery-beat动态添加周期性任务实现过程解析
Nov 26 Python
Python使用tkinter制作在线翻译软件
Feb 22 Python
PyQt使用QPropertyAnimation开发简单动画
Apr 02 #Python
python topk()函数求最大和最小值实例
Apr 02 #Python
python使用梯度下降和牛顿法寻找Rosenbrock函数最小值实例
Apr 02 #Python
Python如何通过百度翻译API实现翻译功能
Apr 02 #Python
Python基于百度AI实现OCR文字识别
Apr 02 #Python
python 穷举指定长度的密码例子
Apr 02 #Python
python3安装OCR识别库tesserocr过程图解
Apr 02 #Python
You might like
php strlen mb_strlen计算中英文混排字符串长度
2009/07/10 PHP
php多维数组去掉重复值示例分享
2014/03/02 PHP
php实现批量下载百度云盘文件例子分享
2014/04/10 PHP
利用google提供的API(JavaScript接口)获取网站访问者IP地理位置的代码详解
2010/07/24 Javascript
javascript中动态函数用法实例分析
2015/05/14 Javascript
JS实现点击按钮获取页面高度的方法
2015/11/02 Javascript
基于Bootstrap实现Material Design风格表单插件 附源码下载
2016/04/18 Javascript
Javascript小技能总结(推荐)
2016/06/02 Javascript
Google 地图API Map()构造器详解
2016/08/06 Javascript
利用jsonp跨域调用百度js实现搜索框智能提示
2016/08/24 Javascript
详解Javascript数据类型的转换规则
2016/12/12 Javascript
js实现将json数组显示前台table中
2017/01/10 Javascript
bootstrap3 dialog 更强大、更灵活的模态框
2017/04/20 Javascript
详解Vue 非父子组件通信方法(非Vuex)
2017/05/24 Javascript
JS实现仿饿了么在浏览器标签页失去焦点时网页Title改变
2017/06/01 Javascript
使用node.js对音视频文件加密的实例代码
2017/08/30 Javascript
vue中eslintrc.js配置最详细介绍
2018/12/21 Javascript
JavaScript面向对象程序设计中对象的定义和继承详解
2019/07/29 Javascript
Vue数字输入框组件使用方法详解
2020/02/10 Javascript
jQuery实现电梯导航模块
2020/12/22 jQuery
[14:03]2017DOTA2亚洲邀请赛开幕式:12神兵演绎水墨中华
2017/04/01 DOTA
Python聚类算法之基本K均值实例详解
2015/11/20 Python
Centos Python2 升级到Python3的简单实现
2016/06/21 Python
对python中array.sum(axis=?)的用法介绍
2018/06/28 Python
Python日志模块logging基本用法分析
2018/08/23 Python
PyCharm+Qt Designer+PyUIC安装配置教程详解
2019/06/13 Python
python列表的逆序遍历实现
2020/04/20 Python
使用keras实现非线性回归(两种加激活函数的方式)
2020/07/05 Python
css3中less实现文字长阴影(long shadow)
2020/04/24 HTML / CSS
欧洲领先的电子和电信零售商和服务提供商:Currys PC World Business
2017/12/05 全球购物
艺术用品:Arteza
2018/11/25 全球购物
解除劳动合同协议书
2014/04/14 职场文书
学校食堂管理制度
2015/08/04 职场文书
OpenCV图像变换之傅里叶变换的一些应用
2021/07/26 Python
升级 Win11 还是坚守 Win10?微软 Win11 新系统缺失功能大盘点
2022/04/05 数码科技
win11无线投屏在哪设置? win11无线投屏功能的使用方法
2022/04/08 数码科技