python定時(shí)任務(wù)最強(qiáng)框架APScheduler詳細(xì)教程

<h1>APScheduler定時(shí)任務(wù)</h1><p>上次測(cè)試女神聽了我的建議,已經(jīng)做好了要給項(xiàng)目添加定時(shí)任務(wù)的決定了。但是之前提供的四種方式中,她不知道具體選擇哪一個(gè)关炼。為了和女神更近一步,我把我入行近10年收藏的干貨免費(fèi)拿出來(lái)分享給女神匣吊,希望女神凌晨2點(diǎn)再找我的時(shí)候儒拂,不再是因?yàn)橐o他調(diào)程序了。</p><p>Python中定時(shí)任務(wù)的解決方案色鸳,總體來(lái)說(shuō)有四種社痛,分別是:crontab、 scheduler命雀、 Celery蒜哀、 APScheduler,其中 crontab不適合多臺(tái)服務(wù)器的配置吏砂、scheduler太過于簡(jiǎn)單撵儿、 Celery依賴的軟件比較多乘客,比較耗資源。最好的解決方案就是 APScheduler淀歇。</p><p>APScheduler使用起來(lái)十分方便寨典。提供了基于日期、固定時(shí)間間隔以及 crontab類型的任務(wù)房匆。還可以在程序運(yùn)行過程中動(dòng)態(tài)的新增任務(wù)和刪除任務(wù)。在任務(wù)運(yùn)行過程中报亩,還可以把任務(wù)存儲(chǔ)起來(lái)浴鸿,下次啟動(dòng)運(yùn)行依然保留之前的狀態(tài)。另外最重要的一個(gè)特點(diǎn)是弦追,因?yàn)樗腔?Python語(yǔ)言的庫(kù)岳链,所以是可以跨平臺(tái)的,一段代碼劲件,處處運(yùn)行掸哑!</p><p>在這里我來(lái)給大家詳細(xì)介紹一下具體的用法。</p><h2>一零远、安裝:</h2><p>安裝非常簡(jiǎn)單苗分,通過 pip install apscheduler即可。</p><h2>二牵辣、基本使用:</h2><p>先來(lái)看一段代碼摔癣,然后再來(lái)給大家詳細(xì)講解其中的細(xì)節(jié):</p><ol><li><p><img src="https://upload-images.jianshu.io/upload_images/6620012-1e0fa8a3ec47c84b.png" class="uploaded-img" width="auto" height="auto">
</p></li></ol><p>其中 BlockingScheduler是阻塞性的調(diào)度器,是最基本的調(diào)度器纬向,下面調(diào)用 start方法就會(huì)阻塞當(dāng)前進(jìn)程择浊,所以如果你的程序除了調(diào)度進(jìn)程沒有其他后臺(tái)進(jìn)程,那么是可以是否的逾条,否則這個(gè)調(diào)度器會(huì)阻塞你程序的正常執(zhí)行琢岩。</p><p>接下來(lái)就是定義一個(gè) my_clock函數(shù),這個(gè)函數(shù)就是需要定時(shí)調(diào)度的任務(wù)代碼师脂。</p><p>然后就是實(shí)例化一個(gè) BlockingScheduler對(duì)象担孔,并把 my_clock添加到任務(wù)調(diào)度中。然后看 interval參數(shù)危彩,這里用的是間隔的方式來(lái)調(diào)度攒磨,調(diào)度頻率是 seconds=3,也就是每3秒執(zhí)行一次汤徽。</p><p>執(zhí)行結(jié)果如下:<img src="https://upload-images.jianshu.io/upload_images/6620012-219c233a62973760.jpeg" class="uploaded-img" width="auto" height="auto"></p><p>可以看到每隔3秒鐘的時(shí)間會(huì)執(zhí)行一次娩缰。說(shuō)明定時(shí)任務(wù)已經(jīng)成功執(zhí)行了!</p><p>在了解了 APScheduler的基本使用后谒府,再來(lái)對(duì) APScheduler的四個(gè)基本對(duì)象做個(gè)了解拼坎,這樣才能從全局掌握 APScheduler浮毯。</p><h2>三、四個(gè)基本對(duì)象:</h2><h3>1. 觸發(fā)器(triggers):</h3><p>觸發(fā)器就是根據(jù)你指定的觸發(fā)方式泰鸡,比如是按照時(shí)間間隔债蓝,還是按照 crontab觸發(fā),觸發(fā)條件是什么等盛龄。每個(gè)任務(wù)都有自己的觸發(fā)器饰迹。</p><h3>2. 任務(wù)存儲(chǔ)器(job stores):</h3><p>任務(wù)存儲(chǔ)器是可以存儲(chǔ)任務(wù)的地方,默認(rèn)情況下任務(wù)保存在內(nèi)存余舶,也可將任務(wù)保存在各種數(shù)據(jù)庫(kù)中啊鸭。任務(wù)存儲(chǔ)進(jìn)去后,會(huì)進(jìn)行序列化匿值,然后也可以反序列化提取出來(lái)赠制,繼續(xù)執(zhí)行。</p><h3>3. 執(zhí)行器(executors):</h3><p>執(zhí)行器的目的是安排任務(wù)到線程池或者進(jìn)程池中運(yùn)行的挟憔。</p><h3>4. 調(diào)度器(schedulers):</h3><p>任務(wù)調(diào)度器是屬于整個(gè)調(diào)度的總指揮官钟些。他會(huì)合理安排作業(yè)存儲(chǔ)器、執(zhí)行器绊谭、觸發(fā)器進(jìn)行工作政恍,并進(jìn)行添加和刪除任務(wù)等。調(diào)度器通常是只有一個(gè)的达传。開發(fā)人員很少直接操作觸發(fā)器抚垃、存儲(chǔ)器、執(zhí)行器等趟大。因?yàn)檫@些都由調(diào)度器自動(dòng)來(lái)實(shí)現(xiàn)了鹤树。</p><p><img src="https://upload-images.jianshu.io/upload_images/6620012-d7462dd83dc8a2ee.jpeg" class="uploaded-img" width="auto" height="auto"></p><h2>四、觸發(fā)器:</h2><p>觸發(fā)器有兩種逊朽,第一種是 interval罕伯,第二種是 crontab。interval可以具體指定多少時(shí)間間隔執(zhí)行一次叽讳。crontab可以指定執(zhí)行的日期策略追他。以下分別進(jìn)行講解。</p><h3>1.?date觸發(fā)器:</h3><p>在某個(gè)日期時(shí)間只觸發(fā)一次事件岛蚤。示例代碼如下:</p><ol><li><p><img src="https://upload-images.jianshu.io/upload_images/6620012-80b31cb26acd3ef7.png" class="uploaded-img" width="auto" height="auto">
</p></li></ol><p>更多請(qǐng)參考:https://apscheduler.readthedocs.io/en/stable/modules/triggers/date.html</p><h3>2.?interval觸發(fā)器:</h3><p>想要在固定的時(shí)間間隔觸發(fā)事件邑狸。interval的觸發(fā)器可以設(shè)置以下的觸發(fā)參數(shù):</p><ol><li><p>weeks:周。整形涤妒。</p></li><li><p>days:一個(gè)月中的第幾天单雾。整形。</p></li><li><p>hours:小時(shí)。整形硅堆。</p></li><li><p>minutes:分鐘屿储。整形。</p></li><li><p>seconds:秒渐逃。整形够掠。</p></li><li><p>start_date:間隔觸發(fā)的起始時(shí)間。</p></li><li><p>end_date:間隔觸發(fā)的結(jié)束時(shí)間茄菊。</p></li><li><p>jitter:觸發(fā)的時(shí)間誤差疯潭。</p></li></ol><ol><li><p><img src="https://upload-images.jianshu.io/upload_images/6620012-ffa0348917bdfa7b.png" class="uploaded-img" width="auto" height="auto">
</p></li></ol><p>在每天的11點(diǎn)24分觸發(fā)事件。更多請(qǐng)參考:https://apscheduler.readthedocs.io/en/stable/modules/triggers/interval.html</p><h3>3.?crontab觸發(fā)器:</h3><p>在某個(gè)確切的時(shí)間周期性的觸發(fā)事件面殖≡祝可以使用的參數(shù)如下:</p><ol><li><p>year:4位數(shù)字的年份。</p></li><li><p>month:1-12月份畜普。</p></li><li><p>day:1-31日。</p></li><li><p>week:1-53周群叶。</p></li><li><p>day_of_week:一個(gè)禮拜中的第幾天(?0-6或者?mon吃挑、?tue、?wed街立、?thu舶衬、?fri、?sat赎离、?sun)逛犹。</p></li><li><p>hour:?0-23小時(shí)。</p></li><li><p>minute:?0-59分鐘梁剔。</p></li><li><p>second:?0-59秒虽画。</p></li><li><p>start_date:?datetime類型或者字符串類型,起始時(shí)間荣病。</p></li><li><p>end_date:?datetime類型或者字符串類型码撰,結(jié)束時(shí)間。</p></li><li><p>timezone:時(shí)區(qū)个盆。</p></li><li><p>jitter:任務(wù)觸發(fā)的誤差時(shí)間脖岛。</p></li></ol><p>也可以用表達(dá)式類型,可以用以下方式:</p><p><img src="https://upload-images.jianshu.io/upload_images/6620012-6e55bcdb764984f5.png" class="uploaded-img" width="auto" height="auto">
</p><p>示例如下:</p><ol><li><p><img src="https://upload-images.jianshu.io/upload_images/6620012-45883e58e1b4cabe.png" class="uploaded-img" width="auto" height="auto">
</p></li></ol><h2>五颊亮、調(diào)度器:</h2><ol><li><p>BlockingScheduler:適用于調(diào)度程序是進(jìn)程中唯一運(yùn)行的進(jìn)程柴梆,調(diào)用?start函數(shù)會(huì)阻塞當(dāng)前線程,不能立即返回终惑。</p></li><li><p>BackgroundScheduler:適用于調(diào)度程序在應(yīng)用程序的后臺(tái)運(yùn)行绍在,調(diào)用?start后主線程不會(huì)阻塞。</p></li><li><p>AsyncIOScheduler:適用于使用了?asyncio模塊的應(yīng)用程序。</p></li><li><p>GeventScheduler:適用于使用?gevent模塊的應(yīng)用程序揣苏。</p></li><li><p>TwistedScheduler:適用于構(gòu)建?Twisted的應(yīng)用程序悯嗓。</p></li><li><p>QtScheduler:適用于構(gòu)建?Qt的應(yīng)用程序。</p></li></ol><h2>六卸察、任務(wù)存儲(chǔ)器:</h2><p>任務(wù)存儲(chǔ)器的選擇有兩種脯厨。一是內(nèi)存,也是默認(rèn)的配置坑质。二是數(shù)據(jù)庫(kù)合武。使用內(nèi)存的方式是簡(jiǎn)單高效,但是不好的是涡扼,一旦程序出現(xiàn)問題稼跳,重新運(yùn)行的話,會(huì)把之前已經(jīng)執(zhí)行了的任務(wù)重新執(zhí)行一遍吃沪。數(shù)據(jù)庫(kù)則可以在程序崩潰后汤善,重新運(yùn)行可以從之前中斷的地方恢復(fù)正常運(yùn)行。有以下幾種選擇:</p><ol><li><p>MemoryJobStore:沒有序列化票彪,任務(wù)存儲(chǔ)在內(nèi)存中红淡,增刪改查都是在內(nèi)存中完成。</p></li><li><p>SQLAlchemyJobStore:使用?SQLAlchemy這個(gè)?ORM框架作為存儲(chǔ)方式降铸。</p></li><li><p>MongoDBJobStore:使用?mongodb作為存儲(chǔ)器在旱。</p></li><li><p>RedisJobStore:使用?redis作為存儲(chǔ)器。</p></li></ol><h2>七推掸、執(zhí)行器:</h2><p>執(zhí)行器的選擇取決于應(yīng)用場(chǎng)景桶蝎。通常默認(rèn)的 ThreadPoolExecutor已經(jīng)在大部分情況下是可以滿足我們需求的。如果我們的任務(wù)涉及到一些 CPU密集計(jì)算的操作谅畅。那么應(yīng)該考慮 ProcessPoolExecutor登渣。然后針對(duì)每種程序, apscheduler也設(shè)置了不同的 executor:</p><ol><li><p>ThreadPoolExecutor:線程池執(zhí)行器毡泻。</p></li><li><p>ProcessPoolExecutor:進(jìn)程池執(zhí)行器绍豁。</p></li><li><p>GeventExecutor:?Gevent程序執(zhí)行器。</p></li><li><p>TornadoExecutor:?Tornado程序執(zhí)行器牙捉。</p></li><li><p>TwistedExecutor:?Twisted程序執(zhí)行器竹揍。</p></li><li><p>AsyncIOExecutor:?asyncio程序執(zhí)行器。</p></li></ol><h2>八邪铲、定時(shí)任務(wù)調(diào)度配置:</h2><p>這里我們用一個(gè)例子來(lái)說(shuō)明芬位。比如我想這樣配置</p><ol><li><p>執(zhí)行器:</p></li><ul><li><p>配置?default執(zhí)行器為?ThreadPoolExecutor,并且設(shè)置最多的線程數(shù)是20個(gè)带到。</p></li><li><p><</p></li></ul><li><p>存儲(chǔ)器:</p></li><ul><li><p>配置?default的任務(wù)存儲(chǔ)器為?SQLAlchemyJobStore(使用SQLite)昧碉。</p></li><li><p><</p></li></ul><li><p>任務(wù)配置:</p></li><li><p>設(shè)置?coalesce為?False:設(shè)置這個(gè)目的是,比如由于某個(gè)原因?qū)е履硞€(gè)任務(wù)積攢了很多次沒有執(zhí)行(比如有一個(gè)任務(wù)是1分鐘跑一次,但是系統(tǒng)原因斷了5分鐘)被饿,如果?coalesce=True四康,那么下次恢復(fù)運(yùn)行的時(shí)候,會(huì)只執(zhí)行一次狭握,而如果設(shè)置?coalesce=False闪金,那么就不會(huì)合并,會(huì)5次全部執(zhí)行论颅。</p></li><li><p>max_instances=5:同一個(gè)任務(wù)同一時(shí)間最多只能有5個(gè)實(shí)例在運(yùn)行哎垦。比如一個(gè)耗時(shí)10分鐘的job,被指定每分鐘運(yùn)行1次恃疯,如果我?max_instance值5漏设,那么在第6~10分鐘上,新的運(yùn)行實(shí)例不會(huì)被執(zhí)行今妄,因?yàn)橐呀?jīng)有5個(gè)實(shí)例在跑了郑口。</p></li></ol><p>那么代碼如下:</p><ol><li><p><img src="https://upload-images.jianshu.io/upload_images/6620012-e6d38e76ad9fbb9e.png" class="uploaded-img" width="auto" height="auto"><img src="https://upload-images.jianshu.io/upload_images/6620012-834ebd16476ff0c7.png" class="uploaded-img" width="auto" height="auto"><img src="https://upload-images.jianshu.io/upload_images/6620012-2514436bb55ba32b.png" class="uploaded-img" width="auto" height="auto">
</p></li><li><p><span style="color: rgba(0, 0, 0, 0.85); font-size: x-large;">九、任務(wù)操作:</span></p></li></ol><h3>1. 添加任務(wù):</h3><p>使用 scheduler.add_job(job_obj,args,id,trigger,trigger_kwargs)盾鳞。</p><h3>2. 刪除任務(wù):</h3><p>使用 scheduler.remove_job(job_id,jobstore=None)犬性。</p><h3>3. 暫停任務(wù):</h3><p>使用 scheduler.pause_job(job_id,jobstore=None)。</p><h3>4. 恢復(fù)任務(wù):</h3><p>使用 scheduler.resume_job(job_id,jobstore=None)雁仲。</p><h3>5. 修改某個(gè)任務(wù)屬性信息:</h3><p>使用 scheduler.modify_job(job_id,jobstore=None,changes)。</p><h3>6. 修改單個(gè)作業(yè)的觸發(fā)器并更新下次運(yùn)行時(shí)間:</h3><p>使用 scheduler.reschedule_job(job_id,jobstore=None,trigger=None,**trigger_args)</p><h3>7. 輸出作業(yè)信息:</h3><p>使用 scheduler.print_jobs(jobstore=None,out=sys.stdout)</p><h2>十琐脏、異常監(jiān)聽:</h2><p>當(dāng)我們的任務(wù)拋出異常后攒砖,我們可以監(jiān)聽到,然后把錯(cuò)誤信息進(jìn)行記錄日裙。示例代碼如下:</p><ol><li><p>from apscheduler.schedulers.blocking import BlockingScheduler</p></li><li><p>from apscheduler.events import EVENT_JOB_EXECUTED, EVENT_JOB_ERROR</p></li><li><p>import datetime</p></li><li><p>import logging</p></li><li><p>
</p></li><li><p># 配置日志顯示</p></li><li><p><img src="https://upload-images.jianshu.io/upload_images/6620012-9595d5363d1baf09.png" class="uploaded-img" width="auto" height="auto"><img src="https://upload-images.jianshu.io/upload_images/6620012-9ac054139f51377a.png" class="uploaded-img" width="auto" height="auto"><img src="https://upload-images.jianshu.io/upload_images/6620012-aa37af931f761ee0.png" class="uploaded-img" width="auto" height="auto">
</p></li></ol><p>以上便是 APScheduler庫(kù)的詳細(xì)用法了吹艇。如果我們需要在項(xiàng)目中開一個(gè)定時(shí)功能,完全可以選擇 APScheduler昂拂,輕量又功能強(qiáng)大受神。</p><p>這次女神再也不用2點(diǎn)跑到公司去加班啦~</p><p><img src="https://upload-images.jianshu.io/upload_images/6620012-5e2e6e8c43b1338a.png" class="uploaded-img" width="auto" height="auto">
</p>

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市格侯,隨后出現(xiàn)的幾起案子鼻听,更是在濱河造成了極大的恐慌,老刑警劉巖联四,帶你破解...
    沈念sama閱讀 207,248評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件撑碴,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡朝墩,警方通過查閱死者的電腦和手機(jī)醉拓,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人亿卤,你說(shuō)我怎么就攤上這事愤兵。” “怎么了排吴?”我有些...
    開封第一講書人閱讀 153,443評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵秆乳,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我傍念,道長(zhǎng)矫夷,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,475評(píng)論 1 279
  • 正文 為了忘掉前任憋槐,我火速辦了婚禮双藕,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘阳仔。我一直安慰自己忧陪,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,458評(píng)論 5 374
  • 文/花漫 我一把揭開白布近范。 她就那樣靜靜地躺著嘶摊,像睡著了一般。 火紅的嫁衣襯著肌膚如雪评矩。 梳的紋絲不亂的頭發(fā)上叶堆,一...
    開封第一講書人閱讀 49,185評(píng)論 1 284
  • 那天,我揣著相機(jī)與錄音斥杜,去河邊找鬼虱颗。 笑死,一個(gè)胖子當(dāng)著我的面吹牛蔗喂,可吹牛的內(nèi)容都是我干的忘渔。 我是一名探鬼主播,決...
    沈念sama閱讀 38,451評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼缰儿,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼畦粮!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起乖阵,我...
    開封第一講書人閱讀 37,112評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤宣赔,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后瞪浸,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體拉背,經(jīng)...
    沈念sama閱讀 43,609評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,083評(píng)論 2 325
  • 正文 我和宋清朗相戀三年默终,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了椅棺。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片犁罩。...
    茶點(diǎn)故事閱讀 38,163評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖两疚,靈堂內(nèi)的尸體忽然破棺而出床估,到底是詐尸還是另有隱情,我是刑警寧澤诱渤,帶...
    沈念sama閱讀 33,803評(píng)論 4 323
  • 正文 年R本政府宣布丐巫,位于F島的核電站,受9級(jí)特大地震影響勺美,放射性物質(zhì)發(fā)生泄漏递胧。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,357評(píng)論 3 307
  • 文/蒙蒙 一赡茸、第九天 我趴在偏房一處隱蔽的房頂上張望缎脾。 院中可真熱鬧,春花似錦占卧、人聲如沸遗菠。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,357評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)辙纬。三九已至,卻和暖如春叭喜,著一層夾襖步出監(jiān)牢的瞬間贺拣,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,590評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工捂蕴, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留譬涡,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,636評(píng)論 2 355
  • 正文 我出身青樓启绰,卻偏偏與公主長(zhǎng)得像昂儒,于是被迫代替她去往敵國(guó)和親沟使。 傳聞我的和親對(duì)象是個(gè)殘疾皇子委可,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,925評(píng)論 2 344