1.APScheduler的简介:
- Advanced Python Scheduler(APScheduler)是一个Python库,可让您安排Python代码稍后执行,一次或定期执行。(定时任务工具)
- 官方文档
2.APScheduler的特点:
①不依赖于linux的crontab,独立运行。
②可以作为动态添加定时任务。
③可以将添加的任务持久化保存。
3.APScheduler的组件:
- 存储器(job stores)
- 任务存储是安排任务存储在哪里。默认存储只是将任务保留在内存中,但也可以将它们存储在各种类型的数据库中(例如sqlite,mysql,redis等)。
- 触发器(triggers)
- 可以理解为任务什么时候执行。每个任务都有自己的触发器。除了初始配置之外,触发器完全是无状态的。
- 执行器(executors)
- 任务执行人是处理任务的运行。他们通常是将任务提交给线程或进程池来完成此操作。任务完成后,执行程序会通知调度程序,调度程序随后会发出相应的事件。
- 调度器(schedulers)
- 任务调度者是将任务存储(job stores),任务执行人(executors)绑定在一起,起到管理定时任务的作用。通常只在应用程序中运行一个调度程序。应用程序开发人员通常不直接处理作业存储,执行程序或触发器,一般都是通过修改配置信息来实现。配置作业存储和执行程序是通过调度程序完成的,添加,修改和删除任务由调度者管理。
4.安装(pip安装)
pip install apscheduler
5.Python中操作各个组件
- 1.调度器(schedulers):
- BlockingScheduler
from apscheduler.schedulers.blocking import BlockingScheduler """ BlockingScheduler是阻塞模式,即运行到start()时,阻塞 """ scheduler = BlockingScheduler() scheduler.start()
- BackgroundScheduler
from apscheduler.schedulers.background import BackgroundScheduler """ BackgroundScheduler时后台运行模式,即运行到start()时,立即返回 """ scheduler = BackgroundScheduler() scheduler.start()
- BlockingScheduler
- 2.执行器(executors):
- ThreadPoolExecutor------(线程)
from apscheduler.executors.pool import ThreadPoolExecutor from apscheduler.schedulers.background import BackgroundScheduler ''' executor = ThreadPoolExecutor(max_workers=20) 线程池,最多20个线程同时执行 ''' executors = { 'default':ThreadPoolExecutor(max_workers=20) } scheduler = BackgroundScheduler(executors=executors) scheduler.start()
- ProcessPoolExecutor------(进程)
from apscheduler.executors.pool import ProcessPoolExecutor from apscheduler.schedulers.background import BackgroundScheduler ''' executor = ProcessPoolExecutor(max_workers=10) 进程池,最多10个进程同时执行 ''' executors = { 'default':ProcessPoolExecutor(max_workers=10) } scheduler = BackgroundScheduler(executors=executors) scheduler.start()
- ThreadPoolExecutor------(线程)
- 3.存储器(job stores):
- 不需要持久存储,可以存入内存中(MemoryJobStore)
from apscheduler.jobstores.memory import MemoryJobStore from apscheduler.schedulers.background import BackgroundScheduler """ MemoryJobStore是存储在内存中,不提供持久化存储。 """ jobstores = { 'default':MemoryJobStore() } scheduler = BackgroundScheduler(jobstores=jobstores) scheduler.start()
- 需要持久存储,可以结合数据库(SQLAlchemyJobStore)
from apscheduler.jobstores.sqlalchemy import SQLAlchemyJobStore from apscheduler.schedulers.background import BackgroundScheduler """ SQLALchemyJobStore可以连接数据库,提供持久化存储。 """ jobstores = { 'default':SQLAlchemyJobStore(url='sqlite:///demo.sqlite'), # 'default':SQLAlchemyJobStore(url='mysql://root:[email protected]:3306/test') } scheduler = BackgroundScheduler(jobstores=jobstores) scheduler.start()
- 附上其他数据库配置连接(github)
- 不需要持久存储,可以存入内存中(MemoryJobStore)
- 4.触发器(triggers):
- date----(指定某个日期执行一次,或者某个时间执行一次)
from apscheduler.jobstores.sqlalchemy import SQLAlchemyJobStore from apscheduler.executors.pool import ThreadPoolExecutor from apscheduler.schedulers.background import BackgroundScheduler from datetime import date, datetime jobstores = { # 'default':SQLAlchemyJobStore(url='mysql://root:[email protected]:3306/test') 'default':SQLAlchemyJobStore(url='sqlite:///demo.sqlite') } executes = { 'default':ThreadPoolExecutor(10) } def my_job(): print('job1%s' % datetime.now()) """ 出现Unable to determine the name of the local timezone错误 rm -rf /etc/localtime ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime # 如果你是CentOS7就更简单了,单单执行下面命令就OK了 timedatectl set-timezone Asia/Shanghai """ scheduler = BackgroundScheduler(jobstores=jobstores,executes=executes) # scheduler.add_job(my_job,'date',run_date=datetime(2019,11,26,20,49,30)) scheduler.add_job(my_job,'date',run_date='2019-11-26 20:53:30') scheduler.start() while True: pass
- interval----(经过指定的时间间隔执行)
from apscheduler.jobstores.sqlalchemy import SQLAlchemyJobStore from apscheduler.executors.pool import ThreadPoolExecutor from apscheduler.schedulers.background import BackgroundScheduler from datetime import date, datetime """ weeks(int) days(int) hours(int) minutes(int) seconds(int) start_date(datetime|str) end_date(datetime|str) timezone(datetime.tzinfo|str) """ jobstores = { 'default': SQLAlchemyJobStore(url='sqlite:///demo.sqlite') } executes = { 'default': ThreadPoolExecutor(10) } def my_job(p1, p2): print('{}----{}---%s'.format(p1, p2) % datetime.now()) scheduler = BackgroundScheduler(jobstores=jobstores, executes=executes) # scheduler.add_job(my_job, 'interval', seconds=3, args=[10, 20]) scheduler.add_job(my_job, 'interval', hours=3, args=[10, 20], start_date=datetime(2019, 1, 1, 0, 0, 0), end_date=datetime(2019, 1, 2, 0, 0, 0)) scheduler.start() while True: pass
- cron----(按照指定的周期执行)
from apscheduler.jobstores.sqlalchemy import SQLAlchemyJobStore from apscheduler.executors.pool import ThreadPoolExecutor from apscheduler.schedulers.background import BackgroundScheduler from datetime import date, datetime """ 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) """ jobstores = { 'default': SQLAlchemyJobStore(url='sqlite:///demo.sqlite') } executes = { 'default': ThreadPoolExecutor(10) } def my_job(p1, p2): print('{}----{}---%s'.format(p1, p2) % datetime.now()) scheduler = BackgroundScheduler(jobstores=jobstores, executes=executes) # 在7、8、10、12月的第3个周五的00:00, 01:00, 02:00和03:00 执行 scheduler.add_job(my_job,'cron',month='7-8,10-12',day='3rd fri',hour='0-3') # 在2019年12月30日前的周一到周五的5:30执行 scheduler.add_job(my_job,'cron',day_of_week='mon-fri',hour=5,minute=30,end_date='2019-12-30') scheduler.add_job(my_job,'cron',day_of_week='mon-fri',end_date='2019-12-30 05:30:00') scheduler.start() while True: pass
- date----(指定某个日期执行一次,或者某个时间执行一次)
6.对定时任务的操作(Flask)
from flask import Flask
from apscheduler.jobstores.sqlalchemy import SQLAlchemyJobStore
from apscheduler.executors.pool import ThreadPoolExecutor
from apscheduler.schedulers.background import BackgroundScheduler
app = Flask(__name__)
jobstores = {
'default': SQLAlchemyJobStore(url='sqlite:///demo.sqlite')
}
executors = {
'default': ThreadPoolExecutor(max_workers=10)
}
# 使用app对象接管Schedulers
app.schedulers = BackgroundScheduler(jobstores=jobstores, executors=executors)
# 首页
@app.route('/')
def index():
return 'index'
# 定义任务
def my_job():
print('job1')
# 开始任务
@app.route('/start')
def startjob():
app.schedulers.add_job(my_job, 'interval', seconds=3, id='job1')
app.schedulers.start()
return 'start'
# 暂停任务
@app.route('/pause')
def pausejob():
app.schedulers.pause()
return 'pause'
# 恢复任务
@app.route('/resume')
def resumejob():
app.schedulers.resume()
return 'resume'
# 删除任务
@app.route('/remove')
def removejob():
app.schedulers.remove_job('job1')
return 'remove'
if __name__ == '__main__':
# 不定义host,默认使用127.0.0.1:5000
app.run(host='192.168.179.131')