Python-APScheduler模块的使用

分享一个大牛的人工智能教程。零基础!通俗易懂!风趣幽默!希望你也加入到人工智能的队伍中来!请轻击人工智能教程​​icon-default.png?t=O83Ahttps://www.captainai.net/

一、APScheduler

APScheduler 是一个功能强大的 Python 库,用于在后台调度作业,支持多种类型的触发器(如定时、间隔、日期和cron表达式),以及持久化作业存储和分布式执行。相较于schedule库,APScheduler 提供了更多的灵活性和企业级特性,适用于更复杂的调度需求。

APScheduler四个组成部分

1.调度器(Scheduler)

作用:调度器是APScheduler的核心,负责管理和驱动整个任务调度流程。它根据配置的时间规则(触发器)来决定何时执行哪些任务,并管理作业的添加、修改、删除以及执行。

2.触发器(Triggers)
作用:触发器定义了任务执行的时间规则,即决定任务何时触发执行。APScheduler支持几种类型的触发器,包括:

IntervalTrigger:按照固定的时间间隔执行任务,如每隔5分钟执行一次。
DateTrigger:在指定的日期和时间点执行一次任务。
CronTrigger:类似于Unix Cron表达式,提供非常灵活的时间规则,可以精确到秒、分钟、小时、日、月、周几等。

3.作业储存器(Job Stores)
作用:作业储存器用于持久化作业的状态信息,确保任务调度的可靠性。即使程序重启,也能恢复作业的执行状态。APScheduler支持多种作业储存方式,包括内存、SQL数据库(如SQLite、MySQL)、Redis等。

4.执行器(Executors)
作用:执行器负责实际执行作业,它决定了任务在哪个线程或进程中运行。APScheduler提供了多种执行器,例如:

ThreadPoolExecutor:使用线程池来执行任务。
ProcessPoolExecutor:使用进程池来执行任务,适用于CPU密集型任务。
GeventExecutor 或 TornadoExecutor:为异步IO框架(如Gevent或Tornado)设计的执行器,适用于I/O密集型任务。

二、安装

pip install apscheduler

三、创建间隔时间的任务

scheduler = BlockingScheduler()
scheduler.add_job(func, 'interval', seconds=3, args=["desire"])
scheduler.start()

四、调度器

1.BlockingScheduler
阻塞型调度器,最基本的调度器,调用start函数会阻塞当前线程,不能立即返回。
适用于调度程序时进程中唯一运行的进程。

from apscheduler.schedulers.blocking import BlockingScheduler

2.BackgroundScheduler
后台运行调度器,调用start后主线程不会阻塞。
适用于调度程序在应用程序的后台运行。

from apscheduler.schedulers.background import BackgroundScheduler

3.AsyncIOScheduler
适用于使用了asyncio模块的应用程序。

from apscheduler.schedulers.asyncio import AsyncIOScheduler

4.GeventScheduler
适用于使用gevent模块的应用程序。

from apscheduler.schedulers.gevent import GeventScheduler

5.TwistedScheduler
适用于构建Twisted的应用程序。

from apscheduler.schedulers.twisted import TwistedScheduler

6.QtScheduler
适用于构建Qt的应用程序。

from apscheduler.schedulers.qt import QtScheduler

7.TornadoScheduler
适用于构建Tornado的应用程序。

from apscheduler.schedulers.tornado import TornadoScheduler

五、触发器

1.date触发器
在某个时间只触发一次。

scheduler = BlockingScheduler()
# 指定在2022/05/19 16:53 进行执行任务
scheduler.add_job(func, 'date', run_date=datetime(2022, 5, 19, 16, 53), args=["desire"])
scheduler.start()

2.interval触发器
在固定的时间间隔触发事件。

interval触发器可以设置的触发参数:
weeks:周,int
days:一个月中的天,int
hours:小时,int
minutes:分钟,int
seconds:秒,int
start_date:间隔触发的起始时间
end_date:间隔触发的结束时间
jitter:触发的时间误差

scheduler.add_job(func, 'interval', seconds=3, args=["desire"])

3.cron触发器
在某个确切的时间周期性的触发。

参数:

year:4位数的年份
month:1-12月份
day:1-31日
week:1-53周
day_of_week:一周中的第几天
0-6
mon、tue、wed、thu、fri、fri、sat、sun
hour:0-23小时
minute:0-59分钟
second:0-59秒
start_date:datetime类型或字符串类型,起始时间
end_date:datetime类型或字符串累成,结束时间
timezone:时区
jitter:任务触发的误差时间

也可以使用表达式类型:
*:任何 在每个值都触发
*/a:任何 每个a触发一次
a-b:任何 在a-b区间任何一个时间触发(a<b)
a-b/c:任何 在a-b区间内每隔c触发一次
xth y day: 第x个星期y触发
last y day:最后一个星期y触发
last day:一个月中的最后一天触发
x、y、z:任何 可以把上面的表达式进行组合

# 在每个50秒的时候触发
scheduler.add_job(func, 'cron', second=50, args=["desire"])
 
# 在第4个星期日触发
scheduler.add_job(func, 'cron', day="4th sun", args=["desire"])

六、任务存储器

1.MemoryJobStore
没有序列化,任务存储在内存中,增删改查都在内存中完成。

from apscheduler.jobstores.memory import MemoryJobStore

2.SQLAlchemyJobStore
使用SQLAlchemy这个ORM框架作为存储方式。

from apscheduler.jobstores.sqlalchemy import SQLAlchemyJobStore

3.MongoDBJobStore
使用mongodb作为存储器。

from apscheduler.jobstores.mongodb import MongoDBJobStore

4.RedisJobStore
使用redis作为存储器。

from apscheduler.jobstores.redis import RedisJobStore

七、执行器(executors)

1.ThreadPoolExecutor
默认执行器,线程池执行器。

from apscheduler.executors.pool import ThreadPoolExecutor

2.ProcessPoolExecutor
进程池执行器,适用于涉及到一些CPU密集计算的操作。

from apscheduler.executors.pool import ProcessPoolExecutor

3.GeventExecutor
Gevent程序执行器。

from apscheduler.executors.gevent import GeventExecutor

4.TornadoExecutor
Tornado程序执行器。

from apscheduler.executors.tornado import TornadoExecutor

5.TwistedExecutor
Twisted程序执行器。

from apscheduler.executors.twisted import TwistedExecutor

6.AsyncIOExecutor
asyncio程序执行器。

from apscheduler.executors.asyncio import AsyncIOExecutor

八、定时任务调度配置

  • jobstores 用来配置存储器

使用SQLAlchemy进行存储。
使用sqlite数据库,会自动创建数据库,并创建apscheduler_jobs表。

  • executors 用来配置执行器

使用线程池进行执行。
设置最大线程数为20个。

  • job_defaults 创建job时的默认参数
  • coalesce 是否合并执行

比如由于某个原因导致某个任务积攒了很多次没有执行(比如有一个任务是1分钟跑一次,但是系统原因断了5分钟)。如果 coalesce=True,那么下次恢复运行的时候,会只执行一次,而如果设置 coalesce=False,那么就不会合并,会5次全部执行。

  • max_instances 最大实例数, 同一个任务同一时间最多只能有n个实例在运行。

比如一个耗时10分钟的job,被指定每分钟运行1次,如果我 max_instance值5,那么在第6~10分钟上,新的运行实例不会被执行,因为已经有5个实例在跑了。

from apscheduler.schedulers.blocking import BlockingScheduler
from apscheduler.jobstores.sqlalchemy import SQLAlchemyJobStore
from apscheduler.executors.pool import ThreadPoolExecutor
 
interval_task = {
    # 配置存储器
    "jobstores": {
        # 使用SQLAlchemy进行存储,会自动创建数据库,并创建apscheduler_jobs表
        'default': SQLAlchemyJobStore(url="sqlite:///jobs.db")
    },
    # 配置执行器
    "executors": {
        # 使用线程池进行执行,最大线程数是20个
        'default': ThreadPoolExecutor(20)
    },
    # 创建job时的默认参数
    "job_defaults": {
        'coalesce': False,  # 是否合并执行
        'max_instances': 3  # 最大实例数
    }
 
}
scheduler = BlockingScheduler(**interval_task)

九、任务操作

1.添加job
调用add_job()方法。
最常用的方式:
返回一个apscheduler.job.Job实例,可以用它在之后修改或移除job。如果调度的job在一个持久化的存储器里,当初始化应用程序时,必须要为job定义一个显示的ID并使用replace_existing=True, 否则每次应用程序重启时都会得到那个job的一个新副本。
在任务中使用scheduled_job()装饰器:
通过声明job而不修改应用程序运行时是最为方便的。

# 最常用的方式
scheduler.add_job(func, 'interval', seconds=3, args=["desire"], id="desire_job", replace_existing=True)
# 使用装饰器
@scheduler.scheduled_job("interval", seconds=5, id="job2222222")
def test_task():
    now = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    print(now + f" Hello world, 使用装饰器")

2.移除job
1)通过job的ID来调用remove_job方法。
2)通过在add_job()中得到的job实例调用remove()方法。
如果一个job完成了调度(例如他的触发器不会再被触发), 它会自动被移除。

# remove
job = scheduler.add_job(func, 'interval', seconds=3, args=["desire"], id="job_remove")
job.remove()
 
# remove_job
scheduler.add_job(func, 'interval', seconds=3, args=["desire"], id="job_remove")
scheduler.remove_job(job_id="job_remove")

3.暂停和恢复job
通过job实例或者schedule本身可以轻易地暂停和恢复job。当一个job被暂停,他的下一次运行时间将会被清空,同时不再计算之后的运行时间,直到这个job被恢复。

# 暂停一个job
# 方式一:
job = scheduler.add_job(func, 'interval', seconds=3, args=["desire"], id="job_remove")
job.pause()
# 方式二:
scheduler.add_job(func, 'interval', seconds=3, args=["desire"], id="job_remove")
scheduler.pause_job(job_id="job_remove")
 
# 恢复一个job
# 方式一:
job = scheduler.add_job(func, 'interval', seconds=3, args=["desire"], id="job_remove")
job.resume()
# 方式二:
scheduler.add_job(func, 'interval', seconds=3, args=["desire"], id="job_remove")
scheduler.resume_job(job_id="job_remove")

4.获取作业调度列表
get_jobs 获取机器上可处理的作业调度列表:返回一个Job实例列表,如果只对特定的存储器中的job感兴趣,可以将存储器的别名作为第二个参数。
print_jobs 格式化输出作业列表以及他们的触发器和下一次的运行时间。

5.修改job
modify() 通过job实例进行修改属性。
modify_job 通过job的ID进行修改属性。

job = scheduler.add_job(func, 'interval', seconds=3, args=["desire"], id="job_modify")
# modify
job.modify(name="job222")
# modify_job
scheduler.modify_job(job_id="job_modify", name="job2222")

reschedule 通过job实例重新调度job
reschedule_job 通过job的ID进行重新调度job

job = scheduler.add_job(func, 'interval', seconds=3, args=["desire"], id="job_modify")
# reschedule
job.reschedule(trigger='cron', minute='*/5')
# reschedule_job
scheduler.reschedule_job(job_id="job_modify", trigger='cron', minute='*/5')

十、调度器操作

1.终止调度器
shutdown():
默认情况,会终止任务存储器以及执行器,然后等待所有目前执行的job完成后(自动终止)。
wait=False 此参数不会等待任何运行中的任务完成,直接终止。

scheduler.shutdown()

scheduler.shutdown(wait=False)

2.暂停/恢复 job 的运行
scheduler.pause() 暂停被调度的job的运行。
scheduler.resume() 恢复job的运行,会导致调度器在被恢复之前一致处于休眠状态。
scheduler.start(paused=True) 如果没有进行过唤醒,也可以对处于暂停状态的调度器执行start操作,可以有机会在不想要的job运行之前将它们排除掉。

十一、调度器事件操作

add_listener 通过此方法对调度器绑定事件监听器。

def my_listener(event):
    if event.exception:
        print("任务出错了!!!!!!!!!")
    else:
        print("任务正常运行。。。。。")
# 绑定事件监听器,当出现异常或者错误的时,进行监听
scheduler.add_listener(my_listener, mask=EVENT_JOB_EXECUTED | EVENT_JOB_ERROR)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值