APScheduler(Python化的Cron)

轉載自: https://www.cnblogs.com/zhaoyingjie/p/9664081.html

簡介

APScheduler全程為Advanced Python Scheduler,是一款輕量級的Python任務調度框架。它允許你像Cron那樣安排定期執(zhí)行的任務,并且支持Python函數(shù)或任意可調用的對象。官方文檔:https://apscheduler.readthedocs.io/en/latest/userguide.html#basic-concepts

APScheduler安裝

方法一:使用pip安裝
$ pip install apscheduler

APScheduler組件

  • triggers(觸發(fā)器): 觸發(fā)器中包含調度邏輯,每個作業(yè)都由自己的觸發(fā)器來決定下次運行時間。除了他們自己初始配置意外,觸發(fā)器完全是無狀態(tài)的。
  • job stores(作業(yè)存儲器):存儲被調度的作業(yè),默認的作業(yè)存儲器只是簡單地把作業(yè)保存在內存中,其他的作業(yè)存儲器則是將作業(yè)保存在數(shù)據(jù)庫中。當作業(yè)被保存到一個持久化的作業(yè)存儲器中的時候,該作業(yè)的數(shù)據(jù)會被序列化,并在加載時被反序列化。作業(yè)存儲器不能共享調度器。
  • executors(執(zhí)行器):處理作業(yè)的運行,他們通常通過在作業(yè)中提交指定的可調用對象到一個線程或者進城池來進行。當作業(yè)完成時,執(zhí)行器將會通知調度器。
  • schedulers(調度器):配置作業(yè)存儲器和執(zhí)行器可以在調度器中完成,例如添加、修改和移除作業(yè)。根據(jù)不同的應用場景可以選用不同的調度器,可選的有BlockingScheduler,BackgroundScheduler,AsyncIOScheduler,GeventScheduler,TornadoScheduler,TwistedScheduler,QtScheduler 7種。
調度器
  • BlockingScheduler : 當調度器是你應用中唯一要運行的東西時。
  • BackgroundScheduler : 當你沒有運行任何其他框架并希望調度器在你應用的后臺執(zhí)行時使用(充電樁即使用此種方式)。
  • AsyncIOScheduler : 當你的程序使用了asyncio(一個異步框架)的時候使用。
  • GeventScheduler : 當你的程序使用了gevent(高性能的Python并發(fā)框架)的時候使用。
  • TornadoScheduler : 當你的程序基于Tornado(一個web框架)的時候使用。
  • TwistedScheduler : 當你的程序使用了Twisted(一個異步框架)的時候使用
  • QtScheduler : 如果你的應用是一個Qt應用的時候可以使用。
作業(yè)存儲器

如果你的應用在每次啟動的時候都會重新創(chuàng)建作業(yè),那么使用默認的作業(yè)存儲器(MemoryJobStore)即可,但是如果你需要在調度器重啟或者應用程序奔潰的情況下任然保留作業(yè),你應該根據(jù)你的應用環(huán)境來選擇具體的作業(yè)存儲器。例如:使用Mongo或者SQLAlchemy JobStore (用于支持大多數(shù)RDBMS)

執(zhí)行器

對執(zhí)行器的選擇取決于你使用上面哪些框架,大多數(shù)情況下,使用默認的ThreadPoolExecutor已經(jīng)能夠滿足需求。如果你的應用涉及到CPU密集型操作,你可以考慮使用ProcessPoolExecutor來使用更多的CPU核心。你也可以同時使用兩者,將ProcessPoolExecutor作為第二執(zhí)行器。

觸發(fā)器

當你調度作業(yè)的時候,你需要為這個作業(yè)選擇一個觸發(fā)器,用來描述這個作業(yè)何時被觸發(fā),APScheduler有三種內置的觸發(fā)器類型:

  • date 一次性指定日期
    最基本的一種調度,作業(yè)只會執(zhí)行一次。它的參數(shù)如下:
    run_date (datetime|str) – 作業(yè)的運行日期或時間
    timezone (datetime.tzinfo|str) – 指定時區(qū)
# 2016-12-12運行一次job_function
sched.add_job(job_function, 'date', run_date=date(2016, 12, 12), args=['text'])
# 2016-12-12 12:00:00運行一次job_function
sched.add_job(job_function, 'date', run_date=datetime(2016, 12, 12, 12, 0, 0), args=['text'])
  • interval 在某個時間范圍內間隔多長時間執(zhí)行一次
    間隔調度,參數(shù)如下:
    weeks (int) – 間隔幾周
    days (int) – 間隔幾天
    hours (int) – 間隔幾小時
    minutes (int) – 間隔幾分鐘
    seconds (int) – 間隔多少秒
    start_date (datetime|str) – 開始日期
    end_date (datetime|str) – 結束日期
    timezone (datetime.tzinfo|str) – 時區(qū)
# 每兩個小時調一下job_function
sched.add_job(job_function, 'interval', hours=2)
  • cron 和Linux crontab格式兼容,最為強大
    參數(shù)如下:
    year (int|str) – 年,4位數(shù)字
    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) – 指定時區(qū)
# job_function將會在6,7,8,11,12月的第3個周五的1,2,3點運行
sched.add_job(job_function, 'cron', month='6-8,11-12', day='3rd fri', hour='0-3')
# 截止到2016-12-30 00:00:00,每周一到周五早上五點半運行job_function
sched.add_job(job_function, 'cron', day_of_week='mon-fri', hour=5, minute=30, end_date='2016-12-31')
配置調度程序

在應用程序中使用默認作業(yè)存儲和默認執(zhí)行程序運行BackgroundScheduler的例子:

from apscheduler.schedulers.background import BackgroundScheduler
scheduler = BackgroundScheduler()

這將生成一個名為“default”的MemoryJobStore和名為“default”的ThreadPoolExecutor的BackgroundScheduler,默認最大線程數(shù)為10。
如果不滿足于當前配置,如希望使用兩個執(zhí)行器有兩個作業(yè)存儲器,并且還想要調整新作業(yè)的默認值并設置不同的時區(qū),可按如下配置:

from apscheduler.schedulers.background import BackgroundScheduler
from apscheduler.jobstores.mongodb import MongoDBJobStore
from apscheduler.jobstores.sqlalchemy import SQLAlchemyJobStore
from apscheduler.executors.pool import ThreadPoolExecutor, ProcessPoolExecutor

 # 配置作業(yè)存儲器
jobstores = {      
    'mongo': MongoDBJobStore(),
    'default': SQLAlchemyJobStore(url='sqlite:///jobs.sqlite')
}
# 配置執(zhí)行器,并設置線程數(shù)
executors = {
    'default': ThreadPoolExecutor(20),
    'processpool': ProcessPoolExecutor(5)
}
job_defaults = {
    'coalesce': False,     # 默認情況下關閉新的作業(yè)
    'max_instances': 3     # 設置調度程序將同時運行的特定作業(yè)的最大實例數(shù)3
}
scheduler = BackgroundScheduler(jobstores=jobstores, executors=executors, job_defaults=job_defaults, timezone=utc)
啟動調度器

啟動調度器只需要調用start()方法,對于除BlockingScheduler以外的調度程序,此調用將立即返回,您可以繼續(xù)應用程序的初始化過程,可能會將作業(yè)添加到調度程序。
對于BlockingScheduler,只需在完成初始化步驟后調用start()

scheduler.start()
添加作業(yè)

添加作業(yè)

  • 方法一:調用add_job()方法
    最常見的方法,add_job()方法返回一個apscheduler.job.Job實例,您可以稍后使用它來修改或刪除該作業(yè)。
  • 方法二:使用裝飾器scheduled_job()
    此方法主要是方便的聲明在應用程序運行時不會改變的作業(yè)
刪除作業(yè)
  • 方法一:通過作業(yè)ID或別名調用remove_job()刪除作業(yè)
  • 方法二:通過add_job()返回的job實例調用remove()方法刪除作業(yè)
# 實例刪除
job = scheduler.add_job(myfunc, 'interval', minutes=2)
job.remove()
 # id刪除
scheduler.add_job(myfunc, 'interval', minutes=2, id='my_job_id')
scheduler.remove_job('my_job_id')
暫停和恢復作業(yè)

可以通過Job實例或調度程序本身輕松暫停和恢復作業(yè)。 當作業(yè)暫停時,下一個運行時間將被清除,直到作業(yè)恢復,不會再計算運行時間。 要暫停作業(yè),請使用以下任一方法:

apscheduler.job.Job.pause()
apscheduler.schedulers.base.BaseScheduler.pause_job()

恢復作業(yè):

apscheduler.job.Job.resume()
apscheduler.schedulers.base.BaseScheduler.resume_job()
獲取作業(yè)列表

要獲得計劃作業(yè)的機器可處理列表,可以使用get_jobs()方法。 它將返回一個Job實例列表。 如果您只對特定作業(yè)存儲中包含的作業(yè)感興趣,則將作業(yè)存儲別名作為第二個參數(shù)。
為了方便起見,可以使用print_jobs()方法,它將打印格式化的作業(yè)列表,觸發(fā)器和下次運行時間。

  • 修改作業(yè)屬性
    您可以通過調用apscheduler.job.Job.modify()或modify_job()來修改除id以外的任何作業(yè)屬性。
job.modify(max_instances=6, name='Alternate name')
關閉調度程序

默認情況下,調度程序關閉其作業(yè)存儲和執(zhí)行程序,并等待所有當前正在執(zhí)行的作業(yè)完成,wait=False參數(shù)可選,代表立即停止,不用等待。
scheduler.shutdown(wait=False)

附:1、定時任務運行腳本小例子:

import datetime
from apscheduler.schedulers.blocking import BlockingScheduler

scheduler = BlockingScheduler()   # 后臺運行

 # 設置為每日凌晨00:30:30時執(zhí)行一次調度程序
@scheduler.scheduled_job("cron", day_of_week='*', hour='1', minute='30', second='30')
def rebate():
        print "schedule execute"

if __name__ == '__main__':
    try:
        scheduler.start()
    except (KeyboardInterrupt, SystemExit):
        scheduler.shutdown()
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • 1、 簡介 APScheduler的全稱是Advanced Python Scheduler。它是一個輕量級的 P...
    CoderZS閱讀 1,776評論 0 1
  • 簡介:APScheduler是基于Quartz的一個Python定時任務框架。提供了基于日期、固定時間間隔以及cr...
    小啊小狼閱讀 554評論 0 2
  • 上篇文章,我們了解到有三種辦法能實現(xiàn)定時任務,但是都無法做到循環(huán)執(zhí)行定時任務。因此,需要一個能夠擔當此重任的庫。它...
    猴哥愛讀書閱讀 23,798評論 1 36
  • Python定時任務 在項目中,我們可能遇到有定時任務的需求。其一:定時執(zhí)行任務。例如每天早上 8 點定時推送早報...
    羋學僧閱讀 2,856評論 0 5
  • 1、第一種辦法是最簡單又最暴力。那就是在一個死循環(huán)中,使用線程睡眠函數(shù) sleep()。 這種方法能夠執(zhí)行固定間隔...
    我愛Python閱讀 450評論 0 3

友情鏈接更多精彩內容