【python定时任务框架】APScheduler初探

一、实现定时任务的方法

在实际开发中我们经常会碰上一些重复性或周期性的任务,比如每天定时爬取某个网站的数据等,这类任务通常需要我们进行设定或调度,以便其能够在我们设定好的时间内运行。
在 Python 中对于定时任务的操作主要有以下几个:

1、schedule:第三方模块,该模块适合比较轻量级的一些调度任务,但却不适用于复杂时间的调度
2、APScheduler:第三方定时任务框架,是对 Java 第三方定时任务框架 Quartz 的模仿与移植,能提供比 schedule 更复杂的应用场景,并且各种组件都是模块化,易于使用与二次开发。
3、Celery Beat:属于 celery 分布式任务队列第三方库下的一个定时任务组件,如果使用需要配合 RabbitMQ 或 Redis 这类的消息队列套件,需要花费一定的时间在环境搭建上,但在高版本中已经不支持 Windows。

二、APScheduler 概念与组件

先摆上官方文档:https://apscheduler.readthedocs.io/en/latest/userguide.html

(一) 安装

pip install apscheduler

(二) 四大组件、三大概念

1、四大组件

类似于学scrapy框架那样,学习这个框架前先了解熟悉其构成组件。

  • 触发器(trigger)
  • 作业存储器(job stores)
  • 执行器(executors)
  • 调度器(schedulers)

触发器(trigger)

触发器就是用以触发定时任务的组件,在 APScheduler 中主要是指时间触发器(简而言之就是设定一套时间规则,用来定义这个任务何时被触发),并且主要有三类时间触发器可供使用:

  • date日期触发器。日期触发器主要是在某一日期时间点上运行任务时调用,是 APScheduler里面最简单的一种触发器。通常适用于一次性的任务或作业调度。
  • interval间隔触发器。间隔触发器是在日期触发器基础上扩展了对时间部分,比如时、分、秒、天、周这几个部分的设定。是我们用以对重复性任务进行设定或调度的一个常用调度器。设定了时间部分之后,从起始日期开始(默认是当前)会按照设定的时间去执行任务。
  • croncron 表达式触发器。cron 表达式触发器就等价于 Linux 上的crontab,它主要用于更复杂的日期时间进行设定。但需要注意的是,APScheduler 不支持 6 位及以上的 cron表达式,最多只支持到 5 位。

作业存储器(job stores)

作业存储器主要是用于将设定好的调度任务(作业)进行存储,即便是程序因为意外情况,如断电、电脑或服务器重启时,只要重新运行程序时,APScheduler 就会根据对存储好的调度任务(作业)结果进行判断,如果出现已经过期但未执行的情况会进行相应的操作。
APScheduler默认是使用 memory(内存)的形式,也可以是数据库的形式。
支持且常用的数据库有:

  • sqlalchemy 形式的数据库,如 MySQL、PostgreSQL、SQLite 等。
  • Mongodb 非结构化数据库,用于对非结构化或半结构化数据的存储或操作,如 JSON。
  • redis 内存数据库,通常用作数据缓存来使用。

通常我们可以在创建 Scheduler 实例时创建,或是单独为任务指定。配置的方式相对简单,我们只需要指定对应的数据库链接即可。


执行器(executor)

执行器是执行我们任务的对象,在计算机内要么是 CPU 调度任务,要么是单独维护一个线程来运行任务。所以 APScheduler 里的执行器通常是两种: ThreadPoolExecutor 线程池或 ProcessPoolExecutor进程池。

  • AsyncIOExecutor
  • GeventExecutor
  • ThreadPoolExecutor
  • ProcessPoolExecutor
  • TornadoExecutor
  • TwistedExecutor

注意:执行器(Executor)的选择取决于选择何种调度器(scheduler)!!


调度器(schedulers)

Scheduler是APScheduler的核心,调度器的选择主要取决于当前的程序环境以及 APScheduler 的用途。根据用途的不同,APScheduler 提供了以下几种调度器:

  • BlockingScheduler:阻塞调度器,当程序中没有任何存在主进程之中运行东西时,就则使用该调度器。
  • BackgroundScheduler:后台调度器,在不使用后面任何的调度器且希望在应用程序内部运行时的后台启动时才进行使用,如当前你已经开启了一个 Django 或 Flask 服务。
  • AsyncIOScheduler:AsyncIO 调度器,如果代码是通过 asyncio 模块进行异步操作,使用该调度器。
  • GeventScheduler:Gevent 调度器,如果代码是通过 gevent 模块进行协程操作,使用该调度器
  • TornadoScheduler:Tornado 调度器,在 Tornado 框架中使用
  • TwistedScheduler:Twisted 调度器,在基于 Twisted 的框架或应用程序中使用
  • QtScheduler:Qt 调度器,在构建 Qt 应用中进行使用。

通常情况下如果不是和 Web 项目或应用集成共存,往往都首选 BlockingScheduler 调度器来进行操作,它会在当前进程中启动相应的线程来进行任务调度与处理;反之,如果是和 Web 项目或应用共存,那么需要选择 BackgroundScheduler 调度器,因为它不会干扰当前应用的线程或进程状况。


2、三大概念

事件(Event)

Event是APScheduler在进行某些操作时触发相应的事件,用户可以自定义一些函数来监听这些事件,当触发某些Event时,做一些具体的操作。常见比如:Job执行异常事件 EVENT_JOB_ERROR,Job执行时间错过事件 EVENT_JOB_MISSED。
目前APScheduler定义的Event有如下:

  • EVENT_SCHEDULER_STARTED
  • EVENT_SCHEDULER_START
  • EVENT_SCHEDULER_SHUTDOWN
  • EVENT_SCHEDULER_PAUSED
  • EVENT_SCHEDULER_RESUMED
  • EVENT_EXECUTOR_ADDED
  • EVENT_EXECUTOR_REMOVED
  • EVENT_JOBSTORE_ADDED
  • EVENT_JOBSTORE_REMOVED
  • EVENT_ALL_JOBS_REMOVED
  • EVENT_JOB_ADDED
  • EVENT_JOB_REMOVED
  • EVENT_JOB_MODIFIED
  • EVENT_JOB_EXECUTED
  • EVENT_JOB_ERROR
  • EVENT_JOB_MISSED
  • EVENT_JOB_SUBMITTED
  • EVENT_JOB_MAX_INSTANCES

监听事件(Listener)

Listener表示用户自定义监听的一些Event,当Job触发了EVENT_JOB_MISSED事件时可以根据需求做一些其他处理。


作业(job)

Job作为APScheduler最小执行单位。
创建Job时需指定执行的函数、函数所需参数以及Job执行时的一些设置信息。


(三) APScheduler的工作流程

APScheduler 的运行流程:

  1. 设定调度器(scheduler)用以对任务的调度与安排进行全局统筹
  2. 对相应的函数或方法上设定相应的触发器(trigger),并添加到调度器中
  3. 如有任务持久化(job stores)需要则需要设定对应的持久化层,否则默认使用内存存储任务
  4. 当触发器被触发时,就将任务交由执行器(executor)进行执行
    在这里插入图片描述
    在这里插入图片描述
    Scheduler添加job流程

三、代码示例

(一) 触发器代码示例

1、date:日期触发器

最基本的一种调度,作业任务只会执行一次。它表示特定的时间点触发。
两个参数:

参数 说明
run_date (date or datetime or str) 任务运行的日期或者时间
timezone (datetime.tzinfo or str) 指定时区
# date类型
# 该程序会在 2021-01-23 00:00:00 执行 
from datetime import datetime
from apscheduler.schedulers.blocking import BlockingScheduler

scheduler = BlockingScheduler()

def job(text):
    print(text)

scheduler.add_job(job, trigger='date', run_date=datetime(2021, 1, 23), args=['测试任务'])
scheduler.start()

************************************************************************************

# date类型(用于精确时间)
# 该程序会在 2021-01-23 17:38:30 执行
from datetime import datetime
from apscheduler.schedulers.blocking import BlockingScheduler

scheduler = BlockingScheduler()

def job(text):
    print(text)

scheduler.add_job(job, trigger='date', run_date=datetime(2021, 1, 23, 17, 38, 30), args=['测试任务'])
scheduler.start()
2、interval:间隔触发器

八个参数:

参数 说明
weeks (int) 间隔几周
days (int) 间隔几天
hours (int) 间隔几小时
minutes (int) 间隔几分钟
seconds (int) 间隔多少秒
start_date (datetime or str) 最早触发的
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值