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')