python 定时任务框架APScheduler

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/zhang18024666607/article/details/89095265
1、 简介

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

2、 安装

使用 pip 包管理工具安装 APScheduler 是最方便快捷的。

pip install APScheduler

3 、使用步骤

APScheduler 使用起来还算是比较简单。运行一个调度任务只需要以下三部曲。

新建一个 schedulers (调度器) 。
添加一个调度任务(job stores)。
运行调度任务。

下面是执行定时任务的简单示例代码

#!/usr/bin/env python
# coding:utf-8

import time
from apscheduler.schedulers.blocking import BlockingScheduler
import logging

LOG_FORMAT = "%(asctime)s - %(levelname)s - %(message)s"
logging.basicConfig(filename='mypython.log', level=logging.INFO, format=LOG_FORMAT)

today = time.strftime('%Y%m%d', time.localtime(time.time()))
nowDateTime = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))

global num
num = 0

class myAP:
    def __init__(self):
        print("hello")


def sayHello():
    global num
    num = num + 1
    print(nowDateTime+'  任务一  hello word %d' % num)

def sayHello11():
    global num
    num = num + 1
    print(nowDateTime+'  任务二 o(* ̄︶ ̄*)o hello word %d' % num)

if __name__ == "__main__":
    # BlockingScheduler
    scheduler = BlockingScheduler()
    # scheduler.add_job(sayHello, 'cron', day_of_week='0-6', hour=19, minute=50)
    scheduler.add_job(sayHello, 'interval', seconds=2)
    scheduler.add_job(sayHello11, 'interval', seconds=3)
    scheduler.start()

执行结果如图
定时任务执行结果

4、 基础组件

APScheduler 有四种组件,分别是:调度器(scheduler),作业存储(job store),触发器(trigger),执行器(executor)。

schedulers(调度器)
它是任务调度器,属于控制器角色。它配置作业存储器和执行器可以在调度器中完成,例如添加、修改和移除作业。

triggers(触发器)
描述调度任务被触发的条件。不过触发器完全是无状态的。

job stores(作业存储器)
任务持久化仓库,默认保存任务在内存中,也可将任务保存都各种数据库中,任务中的数据序列化后保存到持久化数据库,从数据库加载后又反序列化。

executors(执行器)
负责处理作业的运行,它们通常通过在作业中提交指定的可调用对象到一个线程或者进城池来进行。当作业完成时,执行器将会通知调度器。

4.1 schedulers(调度器)

我个人觉得 APScheduler 非常好用的原因。它提供 7 种调度器,能够满足我们各种场景的需要。例如:后台执行某个操作,异步执行操作等。调度器分别是:

BlockingScheduler : 调度器在当前进程的主线程中运行,也就是会阻塞当前线程。
BackgroundScheduler : 调度器在后台线程中运行,不会阻塞当前线程。
AsyncIOScheduler : 结合 asyncio 模块(一个异步框架)一起使用。
GeventScheduler : 程序中使用 gevent(高性能的Python并发框架)作为IO模型,和 GeventExecutor 配合使用。
TornadoScheduler : 程序中使用 Tornado(一个web框架)的IO模型,用 ioloop.add_timeout 完成定时唤醒。
TwistedScheduler : 配合 TwistedExecutor,用 reactor.callLater 完成定时唤醒。
QtScheduler : 你的应用是一个 Qt 应用,需使用QTimer完成定时唤醒。

4.2 triggers(触发器)

APScheduler 有三种内建的 trigger:
1)date 触发器
date 是最基本的一种调度,作业任务只会执行一次。它表示特定的时间点触发。它的参数如下:

参数 说明
run_date (datetime 或 str) 作业的运行日期或时间
timezone (datetime.tzinfo 或 str) 指定时区

date 触发器使用示例如下:

from datetime import datetime
from datetime import date
from apscheduler.schedulers.background import BackgroundScheduler

def job_func(text):
    print(text)

scheduler = BackgroundScheduler()
# 在 2017-12-13 时刻运行一次 job_func 方法
scheduler .add_job(job_func, 'date', run_date=date(2017, 12, 13), args=['text'])
# 在 2017-12-13 14:00:00 时刻运行一次 job_func 方法
scheduler .add_job(job_func, 'date', run_date=datetime(2017, 12, 13, 14, 0, 0), args=['text'])
# 在 2017-12-13 14:00:01 时刻运行一次 job_func 方法
scheduler .add_job(job_func, 'date', run_date='2017-12-13 14:00:01', args=['text'])
scheduler.start()

interval 触发器

固定时间间隔触发。interval 间隔调度,参数如下:

参数 说明
weeks (int) 间隔几周
days (int) 间隔几天
hours (int) 间隔几小时
minutes (int) 间隔几分钟
seconds (int) 间隔多少秒
start_date (datetime 或 str) 开始日期
end_date (datetime 或 str) 结束日期
timezone (datetime.tzinfo 或str) 时区
cron 触发器

在特定时间周期性地触发,和Linux crontab格式兼容。它是功能最强大的触发器。
我们先了解 cron 参数:

参数 说明
year (int 或 str) 年,4位数字
month (int 或 str) 月 (范围1-12)
day (int 或 str) 日 (范围1-31
week (int 或 str) 周 (范围1-53)
day_of_week (int 或 str) 周内第几天或者星期几 (范围0-6 或者mon,tue,wed,thu,fri,sat,sun)
hour (int 或 str) 时 (范围0-23)
minute (int 或 str) 分 (范围0-59)
second (int 或 str) 秒 (范围0-59)
start_date (datetime 或 str) 最早开始日期(包含)
end_date (datetime 或 str) 最晚结束时间(包含)
timezone (datetime.tzinfo 或str) 指定时区

cron 触发器使用示例如下:

import datetime
from apscheduler.schedulers.background import BackgroundScheduler

def job_func(text): print("当前时间:", datetime.datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S.%f")[:-3])
scheduler = BackgroundScheduler() 

# 在每年 1-3、7-9 月份中的每个星期一、二中的 00:00, 01:00, 02:00 和 03:00 执行 job_func 任务
scheduler .add_job(job_func, 'cron', month='1-3,7-9',day='0, tue', hour='0-3') 
scheduler.start()

4.3 作业存储(job store)

该组件是对调度任务的管理。
1)添加 job
有两种添加方法,其中一种上述代码用到的 add_job(), 另一种则是scheduled_job()修饰器来修饰函数。

这个两种办法的区别是:第一种方法返回一个 apscheduler.job.Job 的实例,可以用来改变或者移除 job。第二种方法只适用于应用运行期间不会改变的 job。

第二种添加任务方式的例子:

@scheduler.scheduled_job(job_func, 'interval', minutes=2) 
def job_func(text): 
    print(datetime.datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S.%f")[:-3]) 
    scheduler = BackgroundScheduler() 
    scheduler.start()

2)移除 job
移除 job 也有两种方法:remove_job() 和 job.remove()。
remove_job() 是根据 job 的 id 来移除,所以要在 job 创建的时候指定一个 id。
job.remove() 则是对 job 执行 remove 方法即可

scheduler.add_job(job_func, 'interval', minutes=2, id='job_one')
scheduler.remove_job(job_one)
job = add_job(job_func, 'interval', minutes=2, id='job_one')
job.remvoe()

3)获取 job 列表
通过 scheduler.get_jobs() 方法能够获取当前调度器中的所有 job 的列表

修改 job
如果你因计划改变要对 job 进行修改,可以使用Job.modify() 或者 modify_job()方法来修改 job 的属性。但是值得注意的是,job 的 id 是无法被修改的。

scheduler.add_job(job_func, 'interval', minutes=2, id='job_one')
scheduler.start()
# 将触发时间间隔修改成 5分钟
scheduler.modify_job('job_one', minutes=5)

job = scheduler.add_job(job_func, 'interval', minutes=2)
# 将触发时间间隔修改成 5分钟
job.modify(minutes=5)

5)关闭 job
默认情况下调度器会等待所有正在运行的作业完成后,关闭所有的调度器和作业存储。如果你不想等待,可以将 wait 选项设置为 False。

scheduler.shutdown()
scheduler.shutdown(wait=false)
4.4 执行器(executor)

执行器顾名思义是执行调度任务的模块。最常用的 executor 有两种:ProcessPoolExecutor 和 ThreadPoolExecutor

下面是显式设置 job store(使用mongo存储)和 executor 的代码的示例。

from pymongo import MongoClient
from apscheduler.schedulers.blocking import BlockingScheduler
from apscheduler.jobstores.mongodb import MongoDBJobStore
from apscheduler.jobstores.memory import MemoryJobStore
from apscheduler.executors.pool import ThreadPoolExecutor, ProcessPoolExecutor


def my_job():
    print 'hello world'
host = '127.0.0.1'
port = 27017
client = MongoClient(host, port)

jobstores = {
    'mongo': MongoDBJobStore(collection='job', database='test', client=client),
    'default': MemoryJobStore()
}
executors = {
    'default': ThreadPoolExecutor(10),
    'processpool': ProcessPoolExecutor(3)
}
job_defaults = {
    'coalesce': False,
    'max_instances': 3
}
scheduler = BlockingScheduler(jobstores=jobstores, executors=executors, job_defaults=job_defaults)
scheduler.add_job(my_job, 'interval', seconds=5)

try:
    scheduler.start()
except SystemExit:
    client.close()

展开阅读全文

5.4.50.定时任务框架入门

07-21

<p style="font-size:14px;">n <span style="font-size:small;">随着国内IT事业的兴起,越来越多的小伙伴也投身到了开发这个相对高薪的行业来。很多同学进入的方式都是零基础通过培训或者看视频自学,在工作一两年后,发现由于自己的基础太薄弱,想进一步提高自己的能力变得非常 困难。</span>n</p>n<p style="font-size:14px;">n <span style="font-size:small;">现在市面上的视频教程,主要有一下两类:第一类是纯理论的,比如框架、算法、虚拟机等;另一类是Demo级别的项目,如各大培训机构的项目课程。从业这么多年,学习了大量的视频教程,也跟很多毕业三年左右的程序员做过交流,但一直没发现一套特别好的教程,能让小伙伴们从零基础一直到高级进阶,持续得到学习。在工作中,他们也反馈,视频教程各种高大上的技术堆砌,而在实际开发中呢,大部分技术都没有用到,就算是用,也完全不是像教程中那么用的。在面试中,你跟夸夸其谈十分钟,面试官一句,请问你在项目中是怎么用这个技术的,在使用的时候有什么问题?遇到这样的问题,大部分同学们都直接熄火,完全不知所措,为啥呢,因为他在项目中根本没有用过这个技术,只是看了文档、视频,只是跟着教程做了Demo。而技术跟业务如何结合,这应该是大部分同学在工作中最薄弱的环节。甚至,有些同学会唯技术论,面对公司的业务,会去抱怨公司用的技术不新,认为业务不重要。但我要纠正的是,技术的出现本来就是为业务服务的,离开业务谈技术那就是耍流氓。</span>n</p>n<p style="font-size:14px;">n <span style="font-size:small;">早在两年前,我就萌生了这样的想法,既然国内的环境造成了面试修地球,上班拧螺丝的情况,那么我能不能结合我自己做的真实项目,脱敏后给大家分享出来,让各位同学能有一个真实的项目环境去边学边提高,所以,也就有了《从0开始用Java做"智慧农业物联网"》课程的诞生。</span>n</p>n<p style="font-size:14px;">n <span style="font-size:small;">学习本课程的基本要求:有Java基础,学习过Spring,SpringMVC,Mybatis框架,做过简单项目以上的同学均可学习。但并不代表,本课程就是个入门教程,对于有开发经验的同学们,物联网这个行业是个朝阳产业,也可以说是未来十年发展的蓝海。那我相信,有实体经济支撑的行业绝不会像互联网行业有那样大的泡沫,也绝不会让你工作的没有安全感。对于有志于从事物联网相关工作的同学,对于想从各方面提升自己的各位同学们来说,本课程也非常的适合你们去学习。</span>n</p>n<p style="font-size:14px;">n <span style="font-size:small;">我从12年就开始接触物联网项目,做过智慧猪场、智慧农场、猪联网、云医疗等相关项目,也做过互联网行业,兜兜转转一圈下来,自认为还是积累了很多的经验和教训,那我都会在我课程中对这样的知识有所分享。</span>n</p>n<p style="font-size:14px;">n <span style="font-size:small;">同时,在这个课程中,我既是产品,又是设计,还是开发,还是运维,也是客户,我会从一个项目的全生命周期给大家进行介绍,并且都有相关的落地方案。这样,同学们的眼光就会有所延展,不会仅仅局限在开发这一亩三分地上。</span>n</p>n<p style="font-size:14px;">n <span style="font-size:small;">本课程的亮点:我只能说,亮点很多,很多。。。</span>n</p>n<p style="font-size:14px;">n <span style="font-size:small;">核心如下:产品经理眼中的产品、数据库设计、如何把一个需求变成代码、如何跟物联网设备交互、如何上线一个项目、在需求变更后如何做到不跟产品撕逼。。。</span>n</p>n<p style="font-size:14px;">n <span style="font-size:small;">看到了吧,我不会只让你知道那些高大上的技术点,我向你们学会的是如何做一个完美的产品!</span>n</p>n<p style="font-size:14px;">n <span style="font-size:small;">在这个课程中,你会看到太多太多跟其他教程不同的地方,你看到的不是Demo级别的案例,你看到的绝对是一个工业级别的实现方案。我也希望通过这个课程,同学们能进一步升华自己的视界,你所站的高度,你看问题的不同角度,将决定未来你成长的上限。</span>n</p>n<p style="font-size:14px;">n <span style="font-size:small;">对于本课程的成长忠告:本课程的录制会持续很长时间,是的,你没看错,是很长时间,目前我的预期,起码是在年底之前不会结束,为什么要这样安排,因为我想要分享的内容实在太多,我也不想对课程进行拆分,也不想草草结束,所以,你所能得到的收获一定会足够大,他没有终点。。。</span>n</p>n<p style="font-size:14px;">n <span style="font-size:small;">最终达到的效果:在业务中学技术点,通过技术点让业务变得更优美!</span>n</p>

没有更多推荐了,返回首页