Python定时任务调度——APScheduler
来源:互联网 发布:有毒网络剧 编辑:程序博客网 时间:2024/05/23 11:18
简介
APScheduler 框架可以让用户定时执行或者周期性执行 Python 任务。既可以添加任务也可以删除任务,还可以将任务存储在数据库中。当 APScheduler 重启之后,还会继续执行之前设置的任务。
APScheduler 是跨平台的,注意 APScheduler 既不是守护进程也不是服务,更不是命令行程序。APScheduler 是进程内的调度器,也就是说它的实现原理是在进程内产生内置的阻塞来创建定时服务,以便在预定的时间内执行某个任务。
安装
可以使用 pip 进行安装:
pip install apscheduler
基础概念
APScheduler 由四个组件构成:
- 触发器(triggers)
- 任务仓库(job stores)
- 执行器(executors)
- 调度器(schedulers)
触发器包含了所有定时任务逻辑,每个任务都有一个对应的触发器,触发器决定任何的何时执行,初始配置情况下,触发器是无状态的。
任务仓库保存要执行的任务,其中一个默认的任务仓库将任务保存在内存中,而另外几个任务仓库将任务保存在数据库中。在将任务保存到任务仓库前,会对任务执行序列化操作,当重新读取任务时,再执行反序列化操作。除了默认的任务仓库,其他任务仓库都不会在内存中保存任务,而是作为任务保存、加载、更新以及搜索的一个中间件。任务仓库在定时器之间不能共享。
执行器用来执行定时任务,它只是将要执行的任务放在新的线程或者线程池中运行。执行完毕之后,再通知定时器。
调度器将其它几个组件联系在一起,一般在应用中只有一个调度器,程序开发者不会直接操作触发器、任务仓库或执行器,相反,调度器提供了这个接口。任务仓库以及执行器的配置都是通过调度器来实现的。
选择合适的调度器、任务仓库、执行器和触发器
APScheduler 支持的存储方式有:
- MemoryStore
- SQLAlchemyJobStore,默认使用 SQLite。
- MongoDBJobStore
- ZooKeeperJobStore
- RedisJobStore
- RethinkDBJobStore
如果是非持久任务,使用默认配置的MemoryStore就可以了,如果是持久性任务,那么久需要根据编程环境进行选择了。
APScheduler 中一些常用调度器:
- BlockingScheduler:适合于只在进程中运行单个任务的情况
- BackgroundScheduler: 适合于要求任何在程序后台运行的情况
- AsyncIOScheduler:适合于使用asyncio框架的情况
- GeventScheduler: 适合于使用gevent框架的情况
- TornadoScheduler: 适合于使用Tornado框架的应用
- TwistedScheduler: 适合使用Twisted框架的应用
- QtScheduler: 适合使用QT的情况
大多数情况下,执行器选择ThreadPoolExecutor就可以了,但是如果涉及到比较耗CPU的任务,就可以选择ProcessPoolExecutor,以充分利用多核CPU。,当然也可以同时使用两个执行器。
当调度一个任务时,需要选择一个触发器。这个触发器决定何时执行任务。APScheduler 支持的触发器有三种:
- date:任务仅执行一次
- interval:任务循环执行
- cron:任务定时执行
trigger 对任务的控制
add_job的第二个参数是trigger,它管理着作业的调度方式。它可以为date, interval或者cron。对于不同的trigger,对应的参数也相同。
cron 定时调度
参数:
和Linux的Crontab一样,它的值格式为:
例如:
# Schedules job_function to be run on the third Friday# of June, July, August, November and December at 00:00, 01:00, 02:00 and 03:00sched.add_job(job_function, 'cron', month='6-8,11-12', day='3rd fri', hour='0-3')# Runs from Monday to Friday at 5:30 (am) until 2014-05-30 00:00:00sched.add_job(job_function, 'cron', day_of_week='mon-fri', hour=5, minute=30, end_date='2014-05-30')
interval 间隔调度
参数:
例如:
# Schedule job_function to be called every two hourssched.add_job(job_function, 'interval', hours=2)
date 定时调度
最基本的一种调度,作业只会执行一次。它的参数如下:
例如:
# The job will be executed on November 6th, 2009sched.add_job(my_job, 'date', run_date=date(2009, 11, 6), args=['text'])# The job will be executed on November 6th, 2009 at 16:30:05sched.add_job(my_job, 'date', run_date=datetime(2009, 11, 6, 16, 30, 5), args=['text
使用MemoryStore
使用 MemoryStore、BlockingScheduler 观察 corn、interval、date 的不同。
from datetime import datetimefrom apscheduler.schedulers.blocking import BlockingSchedulerdef alarm(type): print '[%s Alarm] This alarm was scheduled at %s.' % (type, datetime.now().strftime('%Y-%m-%d %H:%M:%S'))# 定时执行def corn_trigger(): global SCHEDULER SCHEDULER.add_job(func=alarm, args=['cron'], trigger='cron', second='*/5', id='corn_job')# 循环执行def interval_trigger(): global SCHEDULER SCHEDULER.add_job(func=alarm, args=['interval'], trigger='interval', seconds=5, id='interval_job')# 一次执行def date_trigger(): global SCHEDULER SCHEDULER.add_job(func=alarm, args=['date'], trigger='date', run_date=datetime.now(), id='date_job')SCHEDULER = BlockingScheduler()if __name__ == '__main__': corn_trigger() interval_trigger() date_trigger() try: SCHEDULER.start() except (KeyboardInterrupt, SystemExit): SCHEDULER.shutdown()
执行结果:
[date Alarm] This alarm was scheduled at 2017-07-22 11:12:42.[cron Alarm] This alarm was scheduled at 2017-07-22 11:12:45.[interval Alarm] This alarm was scheduled at 2017-07-22 11:12:47.[cron Alarm] This alarm was scheduled at 2017-07-22 11:12:50.[interval Alarm] This alarm was scheduled at 2017-07-22 11:12:52.[cron Alarm] This alarm was scheduled at 2017-07-22 11:12:55.[interval Alarm] This alarm was scheduled at 2017-07-22 11:12:57.
任务持久化(SQLAlchemyJobStore)
APScheduler 可以把任务持久化,如持久化到 MySQL 中。当 APScheduler 把任务持久好到 MySQL 时,会默认自动创建一张 apscheduler_jobs:
定时从 MySQL 中查询数据
import MySQLdbimport timeimport loggingfrom datetime import datetimefrom apscheduler.schedulers.background import BackgroundSchedulerfrom apscheduler.executors.pool import ThreadPoolExecutor, ProcessPoolExecutorlogging.basicConfig(level=logging.INFO, format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s', datefmt='%Y-%m-%d %H:%M:%S', filename='log.txt', filemode='a')def query(host, port, user, password, db): conn = MySQLdb.connect(host=host, port=port, user=user, passwd=password, db=db) cr = conn.cursor() cr.execute('select * from score') conn.commit() res = cr.fetchall() print res with open(r'rs.txt', 'a') as f: f.write(str(res) + '\n')if __name__ == '__main__': url = 'mysql://root:123456@localhost:3306/work' executors = { 'default': ThreadPoolExecutor(20), 'processpool': ProcessPoolExecutor(5) } job_defaults = { 'coalesce': False, 'max_instances': 3 } scheduler = BackgroundScheduler(executors=executors, job_defaults=job_defaults) scheduler.add_jobstore('sqlalchemy', url=url) start = datetime.strptime('2017-07-22 11:32:00', '%Y-%m-%d %H:%M:%S') end = datetime.strptime('2017-07-22 11:34:00', '%Y-%m-%d %H:%M:%S') scheduler.add_job(func=query, args=('127.0.0.1', 3306, 'root', '123456', 'test'), trigger='cron', start_date=start, end_date=end, second='*/5', id='query') try: scheduler.start() while True: time.sleep(2) except (KeyboardInterrupt, SystemExit): scheduler.shutdown()
GitHub 上可查看源代码
参考资料
APScheduler User Guide
- Python定时任务调度——APScheduler
- python定时任务调度——apscheduler模块
- python定时任务调度——apscheduler模块
- Python 任务调度-APScheduler
- python定时任务调度库apscheduler的使用
- Python APScheduler任务调度器
- Python定时任务框架APScheduler
- Python定时任务框架APScheduler
- Python定时任务框架APScheduler
- Python定时任务框架APScheduler
- 分布式定时任务框架——python定时任务框架APScheduler扩展
- 分布式定时任务框架——python定时任务框架APScheduler扩展
- 【python】Python任务调度模块 – APScheduler
- Python任务调度模块 – APScheduler
- Python任务调度模块 – APScheduler
- Python任务调度模块 – APScheduler
- Python任务调度模块 – APScheduler
- Python任务调度模块 – APScheduler
- SCWS分词扩展在windows下的安装方法
- Ubuntu14.04下安装PyCharm
- CCF CSP 201703-2 学生排队(Java-100分)
- BFS(普通队列与循环队列实现)---OJ 1241 油田问题
- QT信号和槽的机制
- Python定时任务调度——APScheduler
- Lambda表达式
- LIS最长上升子序列(打印路径)
- petalinux查看xadc 温度
- leetcode(11) Container With Most Water
- iOS 热点 拨打电话 适配
- volatile底层实现原理
- 软件开发 —— 重构(refactor)
- PAT A1099