Python Flask_APScheduler定时任务的正确(最佳)使用

描述 

APScheduler基于Quartz的一个Python定时任务框架,实现了Quartz的所有功能。最近使用Flask框架使用Flask_APScheduler来做定时任务,在使用过程当中也遇到很多问题,例如在定时任务调用的方法中需要用到flask的app.app_context()时,需要使用current_app记录日志时,例如:current_app.logger.info("my_job已执行"),定时任务中使用current_app对象会报错,查看了很多资料,大部分资料都是说没有app就创建一个,这样确实也能解决,但是我总感觉这种解决是有问题的,拿.Net Core来说,使用Quartz.NET定时任务时,定时任务依赖于一个Host(主机)对象,不需要重复创建Host对象,但是Flask的app对象使用过程中却需要重新create app,Quartz.NET也是基于Quartz的定时任务框架,我使用过Quartz.NET,因此始终觉得Flask_APScheduler中create app使用是有问题,终于在过了一段时间后看到一位前辈使用Flask_APScheduler的一篇文章后,瞬间通达了,这个问题终于得到完美解决

 最佳使用Flask_APScheduler

 安装Flask_APScheduler

pip install Flask_APScheduler

1.项目结构图如下:

 

 2.Python 软件包utils下的__init__.py 初始化生成APScheduler对象

这里可以灵活处理,例如:也可以是common软件包下__init__.py里初始化APScheduler

 __init__.py的代码如下:

import atexit
import platform

from flask_apscheduler import APScheduler

# 初始化生成APScheduler对象
scheduler = APScheduler()


def init_scheduler(app):
    # 解决APScheduler定时任务重复执行的问题
    if platform.system() == 'Linux':
        # Linux 环境下
        fcntl = __import__("fcntl")
        f = open('scheduler.lock', 'wb')
        try:
            fcntl.flock(f, fcntl.LOCK_EX | fcntl.LOCK_NB)
            scheduler.init_app(app)
            scheduler.start()
        except Exception as e:
            app.logger.error(e)
            print(e)

        def unlock():
            fcntl.flock(f, fcntl.LOCK_UN)
            f.close()

        atexit.register(unlock)
    else:
        # Window 环境下
        msvcrt = __import__('msvcrt')
        f = open('scheduler.lock', 'wb')
        try:
            msvcrt.locking(f.fileno(), msvcrt.LK_NBLCK, 1)
            scheduler.init_app(app)
            scheduler.start()
        except Exception as e:
            pass

        def _unlock_file():
            try:
                f.seek(0)
                msvcrt.locking(f.fileno(), msvcrt.LK_UNLCK, 1)
            except Exception as e:
                pass
        atexit.register(_unlock_file)

3. config.py配置类代码

class Config:
    JOBS = [
        {
            'id': 'job1',
            'func': 'app:MyService.my_job',  # 注意这里的格式,app 是 Flask 应用对象的名称(app.py),: 后面是任务函数名
            'kwargs': {'job_name': 'job1'},
            'trigger': 'cron',
            'hour': 16,  # 16 点执行
            'minute': 58,  # 58 分执行
            'second': 0  # 0 秒执行
        },
        {
            'id': 'job2',
            'func': 'app:MyService.my_job',  # 注意这里的格式,app 是 Flask 应用对象的名称(app.py),: 后面是任务函数名
            'kwargs': {'job_name': 'job2'},
            'trigger': 'cron',
            'hour': 16,  # 16 点执行
            'minute': 58,  # 58 分执行
            'second': 3  # 3 秒执行
        },
        {
            'id': 'job3',
            'func': 'app:MyService.my_job',  # 注意这里的格式,app 是 Flask 应用对象的名称(app.py),: 后面是任务函数名
            'kwargs': {'job_name': 'job3'},
            'trigger': 'cron',
            'hour': 16,  # 16 点执行
            'minute': 58,  # 58 分执行
            'second': 6  # 6 秒执行
        }
    ]
    # 开启API功能,这样才可以用api的方式去查看和修改定时任务
    SCHEDULER_API_ENABLED = True

4.app.py中代码如下 

from config.config import Config  # 导入Config类的配置
from utils import init_scheduler  # 导入init_scheduler方法
# 创建Flask应用
app = Flask(__name__)
app.config.from_object(Config)  # 读取Config类的配置
init_scheduler(app)  # init_scheduler方法

5. MyService类中的my_job的方法使用app上下文

from flask import current_app  # 导入flask的current_app(当前app)
from utils import scheduler  # 很关键的一步 导入utils.__init__.py 初始化后的scheduler对象

class MyService:

    @classmethod
    def my_job(cls, job_name):
        # # # 此方法在定时任务多的情况下,会有性能问题,少的情况没啥问题
        # app = create_app()
        # with app.app_context():
        #     current_app.logger.info("my_job已执行")
        # #     print(f"my_job,当前时间{datetime.now()}")
        # # 使用全局APP变量
        # get_app()
        # with APP.app_context():
        #     current_app.logger.info(f"{job_name}已执行")
        #     print(f"my_job,当前时间{datetime.now()}")

        with scheduler.app.app_context():   # 这个sheduler是带有app及其上下文的
            current_app.logger.info(f"{job_name}已执行")

不建议使用 创建一个app的方法

create app的链接:https://blog.csdn.net/weixin_41934979/article/details/140406152 

6.执行效果如下: 

 源代码地址:https://gitee.com/jxzcode_admin/flask-project.git

 7.总结

 使用的Python 软件包下的__init__.py文件中初始化生成scheduler对象,此对象项目启动后只生成一次,然后导入scheduler对象,在定时任务执行的方法使用: with scheduler.app.app_context(): 就可以 获取flask当前app上下文,不需要create app,个人觉得这才是真正正确使用Flask_APScheduler

 参考资料

https://blog.csdn.net/arnolan/article/details/84936075

https://www.jianshu.com/p/d5a46b2d2fd3

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/873335.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

828华为云征文|使用sysbench对Mysql应用加速测评

文章目录 ❀前言❀测试环境准备❀测试工具选择❀测试工具安装❀mysql配置❀未开启Mysql加速测试❀开启Mysql加速测试❀总结 ❀前言 大家好,我是早九晚十二。 昨天有梳理一篇关于华为云最新推出的云服务器产品Flexus云服务器X。当时有说过,这次的华为云F…

一个好用的Maven依赖冲突解决插件:Maven Helper

在项目开发,或项目Maven需要新增依赖、项目依赖组件升级时,经常会出现添加后,因为各个模块中有相同的依赖、不同的版本而导致依赖冲突,从而导致项目启动不起来,这种冲突非常恶心,因为是传递依赖所以会看不出…

vulhub ThinkPHP5.0.23远程代码执行漏洞

1.在vulhub打开环境 进入环境存在的文件 docker-compose up -d 2.浏览器访问环境 3.查看是否存在漏洞 /index.php?scaptcha 页面报错说明有可能存在 4.使用hackbar插件发送post请求 _method__construct&filter[]system&methodget&server[REQUEST_METHOD]dir…

排查SQL Server中的内存不足及其他疑难问题

文章目录 引言I DMV 资源信号灯资源信号灯 DMV sys.dm_exec_query_resource_semaphores( 确定查询执行内存的等待)查询性能计数器什么是内存授予?II DBCC MEMORYSTATUS 查询内存对象III DBCC 命令释放多个 SQL Server 内存缓存 - 临时度量值IV 等待资源池 %ls (%ld)中的内存…

高通智能模组:以卓越优势引领科技潮流

一、高通智能模组的崛起与发展 在通信技术发展中,高通智能模组出现。5G 兴起,对模组有更高要求,高通凭借积累和创新捕捉需求。早期致力于研发 5G 技术,优化技术降低功耗提高处理能力,展现性能优势。在竞争中&#xff0…

剪映剪辑影视视频字幕声音批量自动对齐教程

一款智能软件,用它结合剪映或CapCut 你就可以快速将一个视频翻译为另一种语言,非常适合做TikTok中视频的用户,无论是英语区法语区还是日语区,这款名为谷哥剪映助手的软件都能成倍提升你的剪辑效率。 让我来给大家介绍它的使用方法…

基于移动互联网的校内物业报修管理系统设计与实现(论文+源码)_kaic

基于移动互联网的校内物业报修管理系统设计与实现 摘  要 校园后勤服务对于学校的发展至关重要,它不仅是学校管理的基石,也是实现教育目标的关键因素,为学生提供优质的生活环境。如果学校能够提供出色的后勤保障,让师生无需担心…

【自动驾驶】控制算法(七)离散规划轨迹的误差计算

写在前面: 🌟 欢迎光临 清流君 的博客小天地,这里是我分享技术与心得的温馨角落。📝 个人主页:清流君_CSDN博客,期待与您一同探索 移动机器人 领域的无限可能。 🔍 本文系 清流君 原创之作&…

【数据结构与算法】单向链表

【数据结构与算法】单向链表 文章目录 【数据结构与算法】单向链表前言一、单向链表初始化二、单向链表插入与遍历三、单向链表的删除与清空四、单向链表返回长度以及销毁五、完整代码六、单向链表企业版总结 前言 本篇文章就单向链表初始化,插入遍历功能&#xff…

Windows terminal使用说明

1 terminal基本介绍 1 下载 从微软商店上下载的方式网速比较慢,一种直接的方式是直接用命令行运行命令 winget install --idMicrosoft.WindowsTerminal -e# Window Terminal 安装以及使用(2021最新) 2 ssh配置 # 使用Windows Terminal进行SSH登录 1 通过label…

如何做好网络安全

随着互联网技术的飞速发展,网站已成为企业对外展示、交流和服务的重要窗口。然而,随之而来的网站安全问题也日益凸显,给企业的业务发展和用户数据安全带来了巨大威胁。因此,高度重视网站安全已成为网络安全的首要任务。今天我们就…

三相直流无刷电机(BLDC)控制算法实现:BLDC有感启动算法思路分析

一枚从事路径规划算法、运动控制算法、BLDC/FOC电机控制算法、工控、物联网工程师,爱吃土豆。如有需要技术交流或者需要方案帮助、需求:以下为联系方式—V 方案1:通过霍尔传感器IO中断触发换相 1.1 整体执行思路 霍尔传感器U、V、W三相通…

2024国赛数学建模A题B题C题D题E题思路资料模型

开始在本帖实时更新2024国赛数学建模赛题思路代码,文章末尾获取! 持续更新参考思路

FPGA编译与部署方法全方位介绍

FPGA编译与部署是FPGA开发中的核心环节,涉及从代码编写、调试到将设计部署到FPGA硬件的全过程。这个流程需要经过创建项目、编写FPGA VI、模拟调试、编译生成比特流文件,最后将设计部署到硬件上运行。编译的特点在于并行执行能力、定制化硬件实现以及复杂…

string字符会调用new分配堆内存吗

gcc的string默认大小是32个字节,字符串小于等于15直接保存在栈上,超过之后才会使用new分配。

『功能项目』战士的平A特效【35】

我们打开上一篇34武器的切换实例的项目, 本章要做的事情是在战士的每次按A键时在指定位置生成一个平A特效 首先将之前下载的技能拖拽至场景中 完全解压缩后重命名为AEffect 拖拽至预制体文件夹 进入主角动画的战士动画层级 双击第一次攻击 选择Animation 创建事件 …

七. 部署YOLOv8检测器-affine-transformation

目录 前言0. 简述1. 案例运行2. 补充说明3. 代码分析3.1 main.cpp3.2 preprocess.cu 结语下载链接参考 前言 自动驾驶之心推出的 《CUDA与TensorRT部署实战课程》,链接。记录下个人学习笔记,仅供自己参考 本次课程我们来学习课程第七章—部署YOLOv8检测器…

python文件自动化(4)

接上节课内容,在开始正式移动文件到目标文件夹之前,我们需要再思考一个问题。在代码运行之前,阿文的下载文件夹里已经存在一些分类文件夹了,比如图例中“PDF文件”这个文件夹就是已经存在的。这样的话,在程序运行时&am…

SprinBoot+Vue校园数字化图书馆系统的设计与实现

目录 1 项目介绍2 项目截图3 核心代码3.1 Controller3.2 Service3.3 Dao3.4 application.yml3.5 SpringbootApplication3.5 Vue 4 数据库表设计5 文档参考6 计算机毕设选题推荐7 源码获取 1 项目介绍 博主个人介绍:CSDN认证博客专家,CSDN平台Java领域优质…

FreeRTOS任务调度(抢占式、协作式、时间片轮转)

任务调度 文章目录 任务调度前言一、协作式二、时间片轮转三、抢占式总结 前言 FreeRTOS 是一个开源的实时操作系统,它支持多种调度策略,包括协作式(cooperative)和抢占式(preemptive)调度。 一、协作式 …