解决方案:APScheduler定时任务不执行,报错Run time of job ... was missed by ...

简介: 解决方案:APScheduler定时任务不执行,报错Run time of job ... was missed by ...


ApScheduler

APScheduler(Advanced Python Scheduler)是一个用于在 Python 应用程序中执行定时任务的库。它提供了一种简单而强大的方式,允许你在指定的时间间隔、日期或特定事件触发时执行任务。

问题背景

最近公司项目中遇到了个 ApScheduler 不执行的奇葩问题,这个项目有两个环境,一个是外网的开发环境,一个是部署到客户现场的内网环境,最近现场反馈好几个定时任务最近到时间都不会执行,而且很随机,有时候就会执行,有时候又不会执行,和抽风了一样。

解决方案

最后定位到是由于现场创建的定时任务太多了(八十多个),APScheduler 默认的调度配置忙不过来了。

最开始的代码写的比较简单,都是基于默认的配置:

...
jobstores = {
    'default': SQLAlchemyJobStore(url='sqlite:///jobs.sqlite')
}
back_scheduler = BackgroundScheduler(timezone="Asia/Shanghai", jobstores=jobstores)
...

翻阅官方文档可以看到,BackgroundScheduler 默认的执行器是 10 个容量的线程执行器。注意这个 10!从下面的文档可以看到。

APScheduler Documentation - Configuring the scheduler

定时任务没有执行可能有两个原因:

  1. 定时任务要执行的时间正好发生了停机/重启。这种情况可能性比较小,除非你真的运气不好,恰好赶在了那个时间。
  2. **Executor 如果是默认的 10 个容量的线程池,恰好 10 个线程都在忙,恰好又有一个任务该执行了,由于没有空闲线程来处理,这个任务将被抛弃。**这个问题就比较常见了,也是我遇到问题的罪魁祸首。如果是因为没有线程处理导致的定时任务不执行,那么会输出日志:Run time of job "xxx (trigger: cron[year='*', month='*', day='*', day_of_week='*', hour='*', minute='*', second='*'], next run at: 2024-01-05 11:17:37 CST)" was missed by 0:00:05.255671,抓住关键词:was missed by,那么基本上就是这个问题了。

这两个原因都可以从官网中找到:

APScheduler Documentation - Missed job executions and coalescing

最后修改代码,适当加大线程池大小,并在创建任务的时候加上 misfire_grace_time 参数。

...
jobstores = {
    'default': SQLAlchemyJobStore(url='sqlite:///jobs.sqlite')
}
job_defaults = {
    'coalesce': True,
    'misfire_grace_time': None
}
# 加大线程池大小
executors = {
    'default': ThreadPoolExecutor(30)
}
back_scheduler = BackgroundScheduler(timezone="Asia/Shanghai", jobstores=jobstores, job_defaults=job_defaults, executors=executors)
...

也可以在创建任务的时候为每个任务单独指定:

...
# 当任务被唤起时,如果在 misfire_grace_time 时间差内,依然运行。
back_scheduler.add_job(... , misfire_grace_time=30)
...

每个任务都有一个 misfire_grace_time,单位:秒,默认是 0 秒。意思是那些错过的任务在有条件执行时(有线程空闲出来/服务已恢复),如果还没有超过 misfire_grace_time,就会被再次执行。如果 misfire_grace_time=None,就是不论任务错过了多长时间,都会再次执行。



相关文章
|
1月前
|
存储 Java 调度
Python定时任务实战:APScheduler从入门到精通
APScheduler是Python强大的定时任务框架,通过触发器、执行器、任务存储和调度器四大组件,灵活实现各类周期性任务。支持内存、数据库、Redis等持久化存储,适用于Web集成、数据抓取、邮件发送等场景,解决传统sleep循环的诸多缺陷,助力构建稳定可靠的自动化系统。(238字)
474 1
|
调度 Python
Python任务调度神器:APScheduler使用详解
Python任务调度神器:APScheduler使用详解
2939 3
|
调度 数据库 Python
python中APScheduler的使用详解(python3经典编程案例)
文章详细讲解了在Python中使用APScheduler来安排和执行定时任务的方法,包括不同调度器的配置与使用场景。
659 0
|
数据采集 调度 数据库
flask-apscheduler的使用与示例
flask-apscheduler的使用与示例
909 4
|
存储 缓存 监控
python任务调度利器-APScheduler
APScheduler是Python的任务调度库,提供基于时间、固定时间点和CRONTAB的任务调度,适用于离线作业和缓存更新等场景。它包含触发器、调度器、任务存储器、执行器和任务事件组件。安装使用`pip install apscheduler`,简单示例展示了如何配置调度器、添加任务并监听任务异常。支持的触发器有间隔、日期和CRON类型,执行器包括线程池和进程池等。任务存储器可选择内存或各种数据库存储。调度器模式有BlockingScheduler和BackgroundScheduler等,可进行任务的添加、删除、暂停和修改,并监听任务事件。5月更文挑战第20天
532 0
|
缓存 JavaScript
Vue 中 computed 与 method 的区别
【10月更文挑战第15天】computed 和 method 是 Vue 中两个重要的选项,它们在功能和特点上存在着明显的区别。理解并合理运用它们的区别,可以帮助我们构建更高效、更具可维护性的 Vue 应用。在实际开发中,要根据具体情况灵活选择使用,以满足不同的需求。
271 2
|
存储 Linux 调度
高效定时任务处理:深入学习Python中APScheduler库的奥秘
高效定时任务处理:深入学习Python中APScheduler库的奥秘
17343 7
高效定时任务处理:深入学习Python中APScheduler库的奥秘
|
存储 Linux 调度
太好用了!Python 定时任务调度框架 APScheduler 详解!
太好用了!Python 定时任务调度框架 APScheduler 详解!
1725 0
|
JavaScript 数据库 Python
一篇文章搞懂flask_sqlalchemy常用操作
这篇文章介绍了Flask框架中SQLAlchemy库的常用操作,包括查询、删除和更新数据的方法和技巧。
843 3
|
数据采集 算法 测试技术
深聊性能测试,从入门到放弃之:Locust性能自动化(二)代码实战
深聊性能测试,从入门到放弃之:Locust性能自动化(二)代码实战
600 1