1.安装  

pip install apscheduler

  

  安装完毕

2. 简单任务

  首先,来个最简单的例子,看看它的威力。

 # coding:utf-8
from apscheduler.schedulers.blocking import BlockingScheduler
import datetime def aps_test():
print datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'), '你好' scheduler = BlockingScheduler()
scheduler.add_job(func=aps_test, trigger='cron', second='*/5')
scheduler.start()

  看代码,定义一个函数,然后定义一个scheduler类型,添加一个job,然后执行,就可以了,代码是不是超级简单,而且非常清晰。看看结果吧。

5秒整倍数,就执行这个函数,是不是超级超级简单?对了,apscheduler就是通俗易懂。

再写一个带参数的。

 # coding:utf-8
from apscheduler.schedulers.blocking import BlockingScheduler
import datetime def aps_test(x):
print datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'), x scheduler = BlockingScheduler()
scheduler.add_job(func=aps_test, args=('你好',), trigger='cron', second='*/5')
scheduler.start()

结果跟上面一样的。

好了,上面只是给大家看的小例子,我们先从头到位梳理一遍吧。apscheduler分为4个模块,分别是Triggers,Job stores,Executors,Schedulers.从上面的例子我们就可以看出来了,triggers就是触发器,上面的代码中,用了cron,其实还有其他触发器,看看它的源码解释。

The ``trigger`` argument can either be:
#. the alias name of the trigger (e.g. ``date``, ``interval`` or ``cron``), in which case any extra keyword
arguments to this method are passed on to the trigger's constructor
#. an instance of a trigger class

看见没有,源码中解释说,有date, interval, cron可供选择,其实看字面意思也可以知道,date表示具体的一次性任务,interval表示循环任务,cron表示定时任务,好了,分别写个代码看看效果最明显。

 # coding:utf-8
from apscheduler.schedulers.blocking import BlockingScheduler
import datetime def aps_test(x):
print datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'), x scheduler = BlockingScheduler()
scheduler.add_job(func=aps_test, args=('定时任务',), trigger='cron', second='*/5')
scheduler.add_job(func=aps_test, args=('一次性任务',), next_run_time=datetime.datetime.now() + datetime.timedelta(seconds=12))
scheduler.add_job(func=aps_test, args=('循环任务',), trigger='interval', seconds=3) scheduler.start()

看看结果

其实应该不用我解释代码,大家也可以看出结果了,非常清晰。除了一次性任务,trigger是不要写的,直接定义next_run_time就可以了,关于date这部分,官网没有解释,但是去看看源码吧,看这行代码。

     def _create_trigger(self, trigger, trigger_args):
if isinstance(trigger, BaseTrigger):
return trigger
elif trigger is None:
trigger = 'date'
elif not isinstance(trigger, six.string_types):
raise TypeError('Expected a trigger instance or string, got %s instead' % trigger.__class__.__name__) # Use the scheduler's time zone if nothing else is specified
trigger_args.setdefault('timezone', self.timezone) # Instantiate the trigger class
return self._create_plugin_instance('trigger', trigger, trigger_args)

第4行,如果trigger为None,直接定义trigger为'date'类型。其实弄到这里,大家应该自己拓展一下,如果实现web的异步任务。假设接到一个移动端任务,任务完成后,发送一个推送到移动端,用date类型的trigger完成可以做的很好。

3.日志

  好了,scheduler的基本应用,我想大家已经会了,但这仅仅只是开始。如果代码有意外咋办?会阻断整个任务吗?如果我要计算密集型的任务咋办?下面有个代码,我们看看会发生什么情况。

 # coding:utf-8
from apscheduler.schedulers.blocking import BlockingScheduler
import datetime def aps_test(x):
print 1/0
print datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'), x scheduler = BlockingScheduler()
scheduler.add_job(func=aps_test, args=('定时任务',), trigger='cron', second='*/5') scheduler.start()

还是上面代码,但我们中间故意加了个错误,看看会发生什么情况。

说我们没有log文件,好吧,我们添加一个log文件,看看写的什么。

 # coding:utf-8
from apscheduler.schedulers.blocking import BlockingScheduler
import datetime
import logging logging.basicConfig(level=logging.INFO,
format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
datefmt='%Y-%m-%d %H:%M:%S',
filename='log1.txt',
filemode='a') def aps_test(x):
print 1/0
print datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'), x scheduler = BlockingScheduler()
scheduler.add_job(func=aps_test, args=('定时任务',), trigger='cron', second='*/5')
scheduler._logger = logging
scheduler.start()

终于可以看到了,这时候才看到错误,这个是一定要注意的。

其实,到这里,完全可以执行大多数任务了,但我们为了效率,安全性,再往下面看看,还有什么。

4.删除任务

假设我们有个奇葩任务,要求执行一定阶段任务以后,删除某一个循环任务,其他任务照常进行。有如下代码:

 # coding:utf-8
from apscheduler.schedulers.blocking import BlockingScheduler
import datetime
import logging logging.basicConfig(level=logging.INFO,
format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
datefmt='%Y-%m-%d %H:%M:%S',
filename='log1.txt',
filemode='a') def aps_test(x):
print datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'), x def aps_date(x):
scheduler.remove_job('interval_task')
print datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'), x scheduler = BlockingScheduler()
scheduler.add_job(func=aps_test, args=('定时任务',), trigger='cron', second='*/5', id='cron_task')
scheduler.add_job(func=aps_date, args=('一次性任务,删除循环任务',), next_run_time=datetime.datetime.now() + datetime.timedelta(seconds=12), id='date_task')
scheduler.add_job(func=aps_test, args=('循环任务',), trigger='interval', seconds=3, id='interval_task')
scheduler._logger = logging scheduler.start()

看看结果,

在运行过程中,成功删除某一个任务,其实就是为每个任务定义一个id,然后remove_job这个id,是不是超级简单,直观?那还有什么呢?

5.停止任务,恢复任务

看看官方文档,还有pause_job, resume_job,用法跟remove_job一样,这边就不详细介绍了,就写个代码。

 # coding:utf-8
from apscheduler.schedulers.blocking import BlockingScheduler
import datetime
import logging logging.basicConfig(level=logging.INFO,
format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
datefmt='%Y-%m-%d %H:%M:%S',
filename='log1.txt',
filemode='a') def aps_test(x):
print datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'), x def aps_pause(x):
scheduler.pause_job('interval_task')
print datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'), x def aps_resume(x):
scheduler.resume_job('interval_task')
print datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'), x scheduler = BlockingScheduler()
scheduler.add_job(func=aps_test, args=('定时任务',), trigger='cron', second='*/5', id='cron_task')
scheduler.add_job(func=aps_pause, args=('一次性任务,停止循环任务',), next_run_time=datetime.datetime.now() + datetime.timedelta(seconds=12), id='pause_task')
scheduler.add_job(func=aps_resume, args=('一次性任务,恢复循环任务',), next_run_time=datetime.datetime.now() + datetime.timedelta(seconds=24), id='resume_task')
scheduler.add_job(func=aps_test, args=('循环任务',), trigger='interval', seconds=3, id='interval_task')
scheduler._logger = logging scheduler.start()

看看结果

是不是很容易?好了,删除任务,停止任务,恢复任务就介绍到这,下面我们看看监听任务。

6.意外

任何代码都可能发生意外,关键是,发生意外了,如何第一时间知道,这才是公司最关心的,apscheduler已经为我们想到了这些。

看下面的代码,

 # coding:utf-8
from apscheduler.schedulers.blocking import BlockingScheduler
from apscheduler.events import EVENT_JOB_EXECUTED, EVENT_JOB_ERROR
import datetime
import logging logging.basicConfig(level=logging.INFO,
format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
datefmt='%Y-%m-%d %H:%M:%S',
filename='log1.txt',
filemode='a') def aps_test(x):
print datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'), x def date_test(x):
print datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'), x
print 1/0 def my_listener(event):
if event.exception:
print '任务出错了!!!!!!'
else:
print '任务照常运行...' scheduler = BlockingScheduler()
scheduler.add_job(func=date_test, args=('一定性任务,会出错',), next_run_time=datetime.datetime.now() + datetime.timedelta(seconds=15), id='date_task')
scheduler.add_job(func=aps_test, args=('循环任务',), trigger='interval', seconds=3, id='interval_task')
scheduler.add_listener(my_listener, EVENT_JOB_EXECUTED | EVENT_JOB_ERROR)
scheduler._logger = logging scheduler.start()

看看结果

是不是很直观,在生产环境中,你可以把出错信息换成发送一封邮件或者发送一个短信,这样定时任务出错就可以立马就知道了。

  好了,今天就讲到这,以后我们有机会再来拓展这个apscheduler,这个非常强大而且直观的后台任务库。

 

7作业运行的控制

add_job的第二个参数是trigger,它管理着作业的调度方式。它可以为date, interval或者cron。对于不同的trigger,对应的参数也相同。

(1). cron定时调度

year (int|str) – 4-digit year
month (int|str) – month (1-12)
day (int|str) – day of the (1-31)
week (int|str) – ISO week (1-53)
day_of_week (int|str) – number or name of weekday (0-6 or mon,tue,wed,thu,fri,sat,sun)
hour (int|str) – hour (0-23)
minute (int|str) – minute (0-59)
second (int|str) – second (0-59)
start_date (datetime|str) – earliest possible date/time to trigger on (inclusive)
end_date (datetime|str) – latest possible date/time to trigger on (inclusive)
timezone (datetime.tzinfo|str) – time zone to use for the date/time calculations (defaults to scheduler timezone)
和Linux的Crontab一样,它的值格式为:

Expression Field Description
* any Fire on every value
*/a any Fire every a values, starting from the minimum
a-b any Fire on any value within the a-b range (a must be smaller than b)
a-b/c any Fire every c values within the a-b range
xth y day Fire on the x -th occurrence of weekday y within the month
last x day Fire on the last occurrence of weekday x within the month
last day Fire on the last day within the month
x,y,z any Fire on any matching expression; can combine any number of any of the above expressions

几个例子如下:

 
1
2
3
4
5
# Schedules job_function to be run on the third Friday
# of June, July, August, November and December at 00:00, 01:00, 02:00 and 03:00
sched.add_job(job_function, 'cron', month='6-8,11-12', day='3rd fri', hour='0-3')
# Runs from Monday to Friday at 5:30 (am) until 2014-05-30 00:00:00
sched.add_job(job_function, 'cron', day_of_week='mon-fri', hour=5, minute=30, end_date='2014-05-30')

(2). interval 间隔调度

它的参数如下:
weeks (int) – number of weeks to wait
days (int) – number of days to wait
hours (int) – number of hours to wait
minutes (int) – number of minutes to wait
seconds (int) – number of seconds to wait
start_date (datetime|str) – starting point for the interval calculation
end_date (datetime|str) – latest possible date/time to trigger on
timezone (datetime.tzinfo|str) – time zone to use for the date/time calculations
例子:

 
1
2
# Schedule job_function to be called every two hours
sched.add_job(job_function, 'interval', hours=2)

(3). date 定时调度

最基本的一种调度,作业只会执行一次。它的参数如下:
run_date (datetime|str) – the date/time to run the job at
timezone (datetime.tzinfo|str) – time zone for run_date if it doesn’t have one already
例子:

 
1
2
3
4
# The job will be executed on November 6th, 2009
sched.add_job(my_job, 'date', run_date=date(2009, 11, 6), args=['text'])
# The job will be executed on November 6th, 2009 at 16:30:05
sched.add_job(my_job, 'date', run_date=datetime(2009, 11, 6, 16, 30, 5), args=['text'])

7.Flask-APScheduler使用

https://www.jianshu.com/p/2628f566b31c

 
参考:
https://www.cnblogs.com/yueerwanwan0204/p/5480870.html
http://debugo.com/apscheduler/

http://jinbitou.net/2016/12/19/2263.html

Python任务调度模块 – APScheduler,实现定时任务的更多相关文章

  1. Python任务调度模块 – APScheduler

    APScheduler是一个Python定时任务框架,使用起来十分方便.提供了基于日期.固定时间间隔以及crontab类型的任务,并且可以持久化任务.并以daemon方式运行应用.目前最新版本为3.0 ...

  2. 【python】Python任务调度模块 – APScheduler

    APScheduler是一个Python定时任务框架,使用起来十分方便.提供了基于日期.固定时间间隔以及crontab类型的任务,并且可以持久化任务.并以daemon方式运行应用.目前最新版本为3.0 ...

  3. Python任务调度模块 – APScheduler。动态修改调度时间间隔

    APScheduler可以把调度任务放到内存里,也可以把任务放到数据库里,那么如何交互式修改定时任务的执行时间间隔或者下次执行时间呢? 方案一:把定时任务放到数据库里,修改数据库里任务的调度时间 方案 ...

  4. 记一次python的任务调度模块apscheduler只在首次执行任务的情况

    最近需要写个日更新的程序,用time.sleep()不能很好的控制任务的执行时间 于是,就使用了python的任务调度模块apscheduler,这个模块功能真的是很强大 具体的就不多讲了 将任务程序 ...

  5. Python定时框架 Apscheduler 详解【转】

    内容来自网络: https://www.cnblogs.com/luxiaojun/p/6567132.html 在平常的工作中几乎有一半的功能模块都需要定时任务来推动,例如项目中有一个定时统计程序, ...

  6. Python使用APScheduler实现定时任务

    APScheduler是基于Quartz的一个Python定时任务框架.提供了基于日期.固定时间间隔以及crontab类型的任务,并且可以持久化任务.在线文档:https://apscheduler. ...

  7. django定时任务python调度框架APScheduler使用详解

    # coding=utf-8 2 """ 3 Demonstrates how to use the background scheduler to schedule a ...

  8. python中的apscheduler模块

    1.简介 apscheduler是python中的任务定时模块,它包含四个组件:触发器(trigger),作业存储(job store),执行器(executor),调度器(scheduler). 2 ...

  9. APScheduler轻量级定时任务框架

    目录 一.APScheduler简介 支持的后端存储作业 集成的Python框架 二.APScheduler下载安装 三.APScheduler组件 各组件简介 调度器 作业存储器 执行器 触发器 四 ...

随机推荐

  1. 多重影分身——C#中多线程的使用二(争抢共享资源)

    只要服务器承受得了,我们可以开任意个线程同时工作以提高效率,然而 两个线程争抢资源可能导致数据混乱. 例如: public class MyFood { public static int Last ...

  2. macOS High Sierra Terminal巨卡问题的解决

    输入命令特别卡,拖拽窗口也特别卡,想到可能和界面渲染有关系,到设置里面把不透明度调成满值,问题解决. 真正的技术原因是看iOS开发相关的书的时候,书里面有这方面渲染消耗的提示说明.

  3. ubuntu 14.04 安装svn server (subversionedge )

    ubuntu 14.04 安装subversionedge 请仔细阅读安装包自带的readme文件! 1.先去官网,找安装包: http://subversion.apache.org/ http:/ ...

  4. HashMap在高并发下如果没有处理线程安全会有怎样的安全隐患,具体表现是什么

    Hashmap在并发环境下,可能出现的问题: 1.多线程put时可能会导致get无限循环,具体表现为CPU使用率100%: 原因:在向HashMap put元素时,会检查HashMap的容量是否足够, ...

  5. 帧同步(LockStep)该如何反外挂

    在中国的游戏环境下,反挂已经成为了游戏开发的重中之重,甚至能决定一款游戏的生死,吃鸡就是一个典型的案例.目前参与了了一款动作射击的MOBA类游戏的开发,同步方案上选择了帧同步技术(LockStep而非 ...

  6. 算法竞赛之递归——输出1-n的所有排列

    本文是博主原创文章,未经允许不得转载.我的csdn博客也同步发布了此文, 链接 https://blog.csdn.net/umbrellalalalala/article/details/79792 ...

  7. DevOps之三 Git的安装与配置

    Centos7 安装Git 一.卸载Centos7 自带的git # git --version git version 1.8.3.1# whereis gitgit: /usr/bin/git / ...

  8. uedit,检测粘贴事件,替换粘贴内容

    vue.editor.addListener("beforepaste",function(type, arg1, arg2){arg1.html="ddddddd&qu ...

  9. python 整理数据中的图片

    import shutil import time import pymysql conn=pymysql.connect(host="222",user="root&q ...

  10. Linux 操作系统基础知识

    1.操作系统总体介绍 •CPU: 就像人的大脑,主要负责相关事情的判断以及实际处理的机制.查询指令: cat /proc/cpuinfo•内存: 大脑中的记忆区块,将皮肤.眼睛等所收集到的信息记录起来 ...