日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學(xué)無先后,達(dá)者為師

網(wǎng)站首頁 編程語言 正文

Python?APScheduler?定時(shí)任務(wù)詳解_python

作者:愛吃辣椒的鍋包肉 ? 更新時(shí)間: 2022-07-25 編程語言

一、基本概念

APScheduler全稱Advanced Python Scheduler 作用為在指定的時(shí)間規(guī)則執(zhí)行指定的作業(yè)。

  • 指定時(shí)間規(guī)則的方式可以是間隔多久執(zhí)行,可以是指定日期時(shí)間的執(zhí)行,也可以類似Linux系統(tǒng)中Crontab中的方式執(zhí)行任務(wù)。
  • 指定的任務(wù)就是一個(gè)Python函數(shù)。

1.1、 觸發(fā)器:triggers

用于設(shè)定觸發(fā)任務(wù)的條件: 觸發(fā)器包含調(diào)度邏輯。每個(gè)任務(wù)都有自己的觸發(fā)器,用于確定何時(shí)應(yīng)該運(yùn)行作業(yè)。除了初始配置之外,觸發(fā)器完全是無狀態(tài)的

1.2、作業(yè)存儲(chǔ)器:job stores

用于存放任務(wù),把任務(wù)存放在內(nèi)存或數(shù)據(jù)庫中

  • 默認(rèn)情況下,任務(wù)存放在內(nèi)存中。也可以配置存放在不同類型的數(shù)據(jù)庫中。如果任務(wù)存放在數(shù)據(jù)庫中,那么任務(wù)的存取有一個(gè)序列化和反序列化的過程,同時(shí)修改和搜索任務(wù)的功能也是由任務(wù)儲(chǔ)存器實(shí)現(xiàn)。
  • 注意一個(gè)任務(wù)儲(chǔ)存器不要共享給多個(gè)調(diào)度器,否則會(huì)導(dǎo)致狀態(tài)混亂

1.3、執(zhí)行器 executors

用于執(zhí)行任務(wù),可以設(shè)定執(zhí)行模式為單線程或線程池:任務(wù)會(huì)被執(zhí)行器放入線程池或進(jìn)程池去執(zhí)行,執(zhí)行完畢后,執(zhí)行器會(huì)通知調(diào)度器。

1.4、調(diào)度器 schedulers

把上方三個(gè)組件作為參數(shù),通過創(chuàng)建調(diào)度器實(shí)例來運(yùn)行:一個(gè)調(diào)度器由上方三個(gè)組件構(gòu)成,一般來說,一個(gè)程序只要有一個(gè)調(diào)度器就可以了。開發(fā)者也不必直接操作任務(wù)儲(chǔ)存器、執(zhí)行器以及觸發(fā)器,因?yàn)檎{(diào)度器提供了統(tǒng)一的接口,通過調(diào)度器就可以操作組件,比如任務(wù)的增刪改查。

在這里插入圖片描述

二、調(diào)度器詳解

  • BlockingScheduler : 阻塞式調(diào)度器:適用于只跑調(diào)度器的程序。
  • BackgroundScheduler: 后臺(tái)調(diào)度器:適用于非阻塞的情況,調(diào)度器會(huì)在后臺(tái)獨(dú)立運(yùn)行
  • AsyncIOScheduler : AsyncIO調(diào)度器,適用于應(yīng)用使用AsnycIO的情況。
  • GeventScheduler : Gevent調(diào)度器,適用于應(yīng)用通過Gevent的情況。
  • TornadoScheduler: Tornado調(diào)度器,適用于構(gòu)建Tornado應(yīng)用。
  • TwistedScheduler:Twisted調(diào)度器,適用于構(gòu)建Twisted應(yīng)用。
  • QtScheduler: Qt調(diào)度器,適用于構(gòu)建Qt應(yīng)用。

2.1、APScheduler有三種內(nèi)置的觸發(fā)器

  • date:日期:觸發(fā)任務(wù)運(yùn)行的具體日期
  • interval: 間隔:觸發(fā)任務(wù)運(yùn)行的時(shí)間間隔
  • cron: 周期:觸發(fā)任務(wù)運(yùn)行的周期

2.2、觸發(fā)器公共參數(shù)

  • id:啟動(dòng)任務(wù)的ID具有唯一性
  • name: 設(shè)置啟動(dòng)任務(wù)的名稱
  • coalesce :當(dāng)由于某種原因?qū)е履硞€(gè)job積攢了好幾次沒有實(shí)際運(yùn)行(比如說系統(tǒng)掛了5分鐘后恢復(fù),有一個(gè)任務(wù)是每分鐘跑一次的,按道理說這5分鐘內(nèi)本來是“計(jì)劃”運(yùn)行5次的,但實(shí)際沒有執(zhí)行),如果coalesce為True,下次這個(gè)job被submit給executor時(shí),只會(huì)執(zhí)行1次,也就是最后這次,如果為False,那么會(huì)執(zhí)行5次(不一定,因?yàn)檫€有其他條件,看后面misfire_grace_time的解釋)
  • max_instance: 就是說同一個(gè)job同一時(shí)間最多有幾個(gè)實(shí)例再跑,比如一個(gè)耗時(shí)10分鐘的job,被指定每分鐘運(yùn)行1次,如果我們max_instance值為5,那么在第6~10分鐘上,新的運(yùn)行實(shí)例不會(huì)被執(zhí)行,因?yàn)橐呀?jīng)有5個(gè)實(shí)例在跑了
  • misfire_grace_time:設(shè)想和上述coalesce類似的場(chǎng)景,如果一個(gè)job本來14:00有一次執(zhí)行,但是由于某種原因沒有被調(diào)度上,現(xiàn)在14:01了,這個(gè)14:00的運(yùn)行實(shí)例被提交時(shí),會(huì)檢查它預(yù)訂運(yùn)行的時(shí)間和當(dāng)下時(shí)間的差值(這里是1分鐘),大于我們?cè)O(shè)置的30秒限制,那么這個(gè)運(yùn)行實(shí)例不會(huì)被執(zhí)行。
  • replace_existing: 如果調(diào)度的job在一個(gè)持久化的存儲(chǔ)器里,當(dāng)初始化應(yīng)用程序時(shí),必須要為job定義一個(gè)顯示的ID并使用replace_existing=True, 否則每次應(yīng)用程序重啟時(shí)都會(huì)得到那個(gè)job的一個(gè)新副本

2.3、date內(nèi)置觸發(fā)器

date 是最基本的一種調(diào)度,作業(yè)任務(wù)只會(huì)執(zhí)行一次。它表示特定的時(shí)間點(diǎn)觸發(fā)。它的參數(shù)如下:

參數(shù) 說明
run_date (datetime 或 str) 作業(yè)的運(yùn)行日期或時(shí)間
timezone (datetime.tzinfo 或 str) 指定時(shí)區(qū)
from datetime import datetime
from datetime import date
from apscheduler.schedulers.blocking import BlockingScheduler
def job(text):
    print(text)
scheduler = BlockingScheduler()
# 在 2019-8-30 運(yùn)行一次 job 方法
scheduler.add_job(job, 'date', run_date=date(2022, 4, 9), args=['text1'], id="1", coalesce=True, max_instances=1)
# 在 2019-8-30 01:00:00 運(yùn)行一次 job 方法
scheduler.add_job(job, 'date', run_date=datetime(2022, 4, 9, 17, 40, 58), args=['text2'], id="2", coalesce=True, max_instances=1)
# 在 2019-8-30 01:00:01 運(yùn)行一次 job 方法
scheduler.add_job(job, 'date', run_date='2022-4-9 17:41:00', args=['text3'], id="3", coalesce=True, max_instances=1)
scheduler.start()

2.4、interval 周期觸發(fā)任務(wù)

參數(shù) 說明
weeks (int) 間隔幾周
days (int) 間隔幾天
hours (int) 間隔幾小時(shí)
minutes (int) 間隔幾分鐘
seconds (int) 間隔多少秒
start_date (datetime 或 str) 開始日期
end_date (datetime 或 str) 結(jié)束日期
timezone (datetime.tzinfo 或str) 時(shí)區(qū)
@sched.scheduled_job(
    "interval", id=spider_job_name + "_bg_data", coalesce=True, max_instances=1, minutes=20
)
def tick_rzjg_detail_xq():
    """
    快速完成
    :return:
    """
    each = "rzjg_bg_data"
    cmd_str = f"cd {ROOT} && bash run_spider.sh {each} --loglevel=INFO"
    print(cmd_str)
    os.system(cmd_str)
def func():
    print("Press Ctrl+C to exit")
    # 直接觸發(fā)一次
    tick_rzjg_detail_xq()
    try:
        sched.start()
    except (KeyboardInterrupt, SystemExit):
        pass

if __name__ == "__main__":
    func()

2.5、cron 觸發(fā)器 在特定時(shí)間周期性地觸發(fā),和Linux crontab格式兼容。

它是功能最強(qiáng)大的觸發(fā)器

參數(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) 周內(nèi)第幾天或者星期幾 (范圍0-6 或者 mon,tue,wed,thu,fri,sat,sun)
hour (int 或 str) 時(shí) (范圍0-23)
minute (int 或 str) 分 (范圍0-59)
second (int 或 str) 秒 (范圍0-59)
start_date (datetime 或 str) 最早開始日期(包含)
end_date (datetime 或 str) 最晚結(jié)束時(shí)間(包含)
timezone (datetime.tzinfo 或str) 指定時(shí)區(qū)
表達(dá)式 參數(shù)類型 描述
* 所有 通配符。例:minutes=*即每分鐘觸發(fā)
*/a 所有 可被a整除的通配符
a-b 所有 范圍a-b觸發(fā)
a-b/c 所有 范圍a-b,且可被c整除時(shí)觸發(fā)
xth y 第幾個(gè)星期幾觸發(fā)。x為第幾個(gè),y為星期幾
last x 一個(gè)月中,最后個(gè)星期幾觸發(fā)
last 一個(gè)月最后一天觸發(fā)
x,y,z 所有 組合表達(dá)式,可以組合確定值或上方的表達(dá)式
 import time
    from apscheduler.schedulers.blocking import BlockingScheduler

    def job(text):
        t = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
        print('{} --- {}'.format(text, t))

    scheduler = BlockingScheduler()
    # 在每天22點(diǎn),每隔 1分鐘 運(yùn)行一次 job 方法
    scheduler.add_job(job, 'cron', hour=22, minute='*/1', args=['job1'])
    # 在每天22和23點(diǎn)的25分,運(yùn)行一次 job 方法
    scheduler.add_job(job, 'cron', hour='22-23', minute='25', args=['job2'])
    # 在每天 8 點(diǎn),運(yùn)行一次 job 方法
    scheduler.add_job(job, 'cron', hour='8', args=['job2'])
    # 在每天 8 點(diǎn) 20點(diǎn),各運(yùn)行一次 job 方法    設(shè)置最大運(yùn)行實(shí)例數(shù)
    scheduler.add_job(job, 'cron', hour='8, 20', minute=30, max_instances=4)
    scheduler.start()

原文鏈接:https://blog.csdn.net/weixin_44301439/article/details/124062178

欄目分類
最近更新