1. 简介与安装

​ Apscheduler是一个轻量级的 Python 定时任务调度框架。APScheduler 支持三种调度任务:固定时间间隔,固定时间点(日期),Linux 下的 Crontab 命令。同时,它还支持异步执行、后台执行调度任务。

pip install apscheduler

2. APScheduler基础组成

2.1 调度器(scheduler)
  • BlockingScheduler: 调度器在当前进程的主线程中运行,会阻塞当前线程。
  • BackgroundScheduler: 调度器在后台线程中运行,不会阻塞当前线程。
  • AsyncIOScheduler: 结合asyncio模块一起使用。
  • GeventScheduler: 程序中使用gevent作为IO模型和GeventExecutor配合使用。
  • TornadoScheduler: 程序中使用Tornado的IO模型,用 ioloop.add_timeout 完成定时唤醒。
  • TwistedScheduler: 配合TwistedExecutor,用reactor.callLater完成定时唤醒。
  • QtScheduler: 应用是一个Qt应用,需使用QTimer完成定时唤醒。
2.2 触发器(trigger)
  • date是最基本的一种调度,作业任务只会执行一次。参数详见
  • interval触发器,固定时间间隔触发。参数详见
  • cron 触发器,在特定时间周期性地触发,和Linux crontab格式兼容。它是功能最强大的触发器。参数详见
2.3 执行器(executor)

执行器是执行调度任务的模块。最常用的 executor 有两种:ProcessPoolExecutorThreadPoolExecutor

2.4 任务存储(job store)

存储预定的作业。默认job store只是将作业保存在内存中,但其他job store将它们存储在各种数据库中。作业的数据在保存到持久job store时被序列化,并在从它加载回来时被反序列化。job store(默认存储除外)不会将作业数据保存在内存中,而是充当中间人,用于在后端保存、加载、更新和搜索作业。job store绝不能在调度程序之间共享。

3. Flask框架实践

3.1 定时任务初始化

apscheduler在app创建时进行初始化, scheduler在初始化器类中进行创建,初始化器类采用单例设计, 在整个flask实例上下文中都是同一个对象,以满足通过接口进行动态更新任务的需求

# src.initializer.py
from apscheduler.schedulers.background import BackgroundSchedulerdef singleton(cls):_instance = {}def _singleton(*args, **kargs):if cls not in _instance:_instance[cls] = cls(*args, **kargs)return _instance[cls]return _singleton@singleton
class Initializer:def __init__(self):self.scheduler = BackgroundScheduler()

scheduler初始化之后可以通过add_job添加一些固定的定时任务, 再通过start方法就可以正式启动定时任务

# main.py
from flask_apscheduler import APScheduler
from src.initializer import Initializerdef create_app():app = Flask(__name__)app.config.from_object(Config)initializer = Initializer()update_job = {"id": "print_jobs","func": "src.utils.common.scheduler:update_jobs","args": (initializer.scheduler,),"trigger": "interval","seconds": 10,}initializer.scheduler.add_job(**update_job)initializer.scheduler.start()return app
3.2 通过接口进行任务动态增减

在初始化flask实例时进行了apscheduler单例化, 可以动态的通过flask接口进行定时任务的删除和新增.使用唯一的job_id进行任务的获取, 删除 和 新增.

from flask import current_app@app.route("/test_apscheduler")
def test_apscheduler():"""测试定时任务动态进行删除和新增任务"""ping_baidu = {"id": "ping_baidu","func": "src.utils.common.scheduler:ping","args": ("baidu.com",),"trigger": "interval","seconds": 10,}job = current_app.apscheduler.get_job(job_id="ping")if job:current_app.apscheduler.remove_job(job_id="ping")current_app.apscheduler.add_job(**ping_baidu)return http_json({"msg": "ok"})
3.3 通过定时任务自我进行任务动态管理

如上在进行flask初始化时有预设一个update_job的定时任务,传参为scheduler调度器, 每2分钟运行一次, 在内部实现任务从配置文件或数据库读取,然后进行任务的删除、更新、新增操作,以此达到定时任务的自我管理。

# 伪代码src.utils.common.scheduler.pydef update_job(scheduler):"""定时任务自我管理,动态更新job"""jobs = scheduler.get_jobs()new_jobs, expired_jobs = get_job_from_db(jobs)for job in expired_jobs:scheduler.remove_job(job_id=job.id)for job in new_jobs:scheduler.add_job(job)

4. 踩坑点

4.1 多进程部署,定时任务重复启动

解决思路: 在启动定时任务时, 设置文件锁, 当不能获取到文件锁时, 不再启动任务


def create_app():app =Flask(__name__)# 启动定时任务scheduler_init(app)return appdef scheduler_init(app):"""保证系统只启动一次定时任务"""if platform.system() != 'Windows':fcntl = __import__("fcntl")f = open('scheduler.lock', 'wb')try:fcntl.flock(f, fcntl.LOCK_EX | fcntl.LOCK_NB)scheduler.init_app(app)scheduler.start()app.logger.debug('Scheduler Started,---------------')except:passdef unlock():fcntl.flock(f, fcntl.LOCK_UN)f.close()atexit.register(unlock)else:msvcrt = __import__('msvcrt')f = open('scheduler.lock', 'wb')try:msvcrt.locking(f.fileno(), msvcrt.LK_NBLCK, 1)scheduler.init_app(app)scheduler.start()app.logger.debug('Scheduler Started,----------------')except:passdef _unlock_file():try:f.seek(0)msvcrt.locking(f.fileno(), msvcrt.LK_UNLCK, 1)except:passatexit.register(_unlock_file)
4.2 多主机分布式部署,定时任务重复启动

apscheduler本身不支持分布式,因此分布式部署还是会出现重复启动问题.

可以多apscheduler进行分布式重写解决, 重写思路: 分布式场景下使用APScheduler 、apscheduler分布式调度

Apscheduler结合flask进行动态任务管理相关推荐

  1. Python Flask,动态路由,url参数,转换器

    demo.py(转换器,动态路由): # coding:utf-8from flask import Flaskapp = Flask(__name__)# 转换器 (动态路由) # 127.0.0. ...

  2. Flask 生成动态二维码登录

    看了很多篇生成动态二维码的帖子,但是,都是片段,前言后语都没有.主要研究的这篇 然后自身也不够理解flask基本语言结构,所以头大, 皇天不负有心人,后来看了一些教程,再加上同事小姐姐指导,终究是给跑 ...

  3. Spring boot2集成quartz动态任务管理+Web UI

    Dynamic Quartz ​ 最近在公司实习,发现公司有一套spring+Quartz的动态任务管理系统.可以使用Web界面进行任务动态的创建.删除.停止.运行和修改.刚好最近在学习spring ...

  4. 使用Redis+Flask维护动态代理池

    1.为什么使用代理池 许多⽹网站有专⻔门的反爬⾍虫措施,可能遇到封IP等问题. 互联⽹网上公开了了⼤大量量免费代理理,利利⽤用好资源. 通过定时的检测维护同样可以得到多个可⽤用代理理. 2.代理池的要 ...

  5. Python爬虫入门之使用Redis+Flask维护动态代理池

    代理池的要求 多站抓取, 异步检测 定时筛选, 持续更新 提供接口, 易于提取 代理池架构 代码 代码放到github上了,稍微修改了一点,可以正常运行了.有问题评论留言讨论. 分为两种ProxyPo ...

  6. Flask自定义转换器,实现路由匹配正则表达式参数

    Flask框架动态路由实现参数传递和Django框架有类似之处,但是相比于Django框架,Flask实现复杂的参数就需要自己自定义转换器来实现了,而不能向Django那样直接使用正则表达式 1 # ...

  7. flask基础(上篇)

    目录 一.flask入门与路由 二.flask路由 三.flask请求响应异常 flask入门与路由 1. flask介绍 Flask是一个基于Python实现的web开发的'微'框架 中文文档地址 ...

  8. flask静态html

    flask使用静态html 在flask并不是所有的html都需要做成动态html,并且做成动态html在使用静态资源时要改变它的路径.所以我们有些可以使用静态html. 静态html不需要后台渲染, ...

  9. python flask安装_python flask安装和命令详解

    Flask Web开发实战学习笔记 Flask简介 Flask是使用Python编写的Web微框架.Web框架可以让我们不用关 心底层的请求响应处理,更方便高效地编写Web程序.因为Flask核心简 ...

最新文章

  1. 清华大学刘知远组:基于Prompt Tuning对低维本征任务子空间进行探索
  2. C++多态,虚函数,纯虚函数
  3. nginx重新安装 引起的问题
  4. python 制作二进制文件数据集(bin)
  5. (68)zabbix windows性能计数器使用详解
  6. django-orm补课-使用shell-新增一行-再增一行-查找行-修改行
  7. #开工新姿势#开启一年新征程,云社区叫你来充电啦!
  8. PHP 文件打开/读取
  9. 0909 对编译原理的想法
  10. Matlab关联m文件与m文件关联设置
  11. 北航计算机组成原理课程设计-2020秋 PreProject-Verilog HDL与ISE-ISE的获取和使用
  12. 限流 Redis list 列表 Lpush rpop 实现令牌桶 – PHP 实例
  13. SpringBoot的pom详解
  14. c++ append用法
  15. Vue的计算属性computed和监听属性watch
  16. 源支付聚合免签支付系统
  17. mysql 匹配多个字符,【单选题】在MySQL语句中,可以匹配0个到多个字符的通配符是( ) A. * B. % C. ? D. –...
  18. DeepSort论文学习
  19. ubuntu16.04上搭建stm32f4开发环境
  20. 双臂模式DPVS+RPM安装教程

热门文章

  1. hadoop--HDFS基础(适合初学者)
  2. 手动挡停车时挂档有技巧
  3. 治数如治水,数据治理和数据创新难在哪?
  4. Dimensionality Reduction - Principle Component Analysis problem formulation
  5. VUE图片裁剪组件,基于VueCropper
  6. 获取字符串第一个数字下标
  7. 微软气坏了!Windows 惨遭抄袭,这款系统简直超越正品
  8. 如何在 GitHub 创建一个“有人用”的项目
  9. 契约锁助力大型能源组织“产-运-储-销-交易”文件电子签
  10. 谷歌浏览器取消自动升级