容器中apscheduler不執行_APScheduler:定時任務框架

APScheduler:定時任務框架

安裝

文檔: https://apscheduler.readthedocs.io/en/stable/userguide.html

安裝

$?pip?install?apscheduler
>>>?import?apscheduler
>>>?apscheduler.version
'3.6.3'

組件

APScheduler由一下四部分組成

  • triggers:觸發器,指定定時任務執行的時機,每個任務都有自己的觸發器.
  • job stores:存儲器,持久存儲,默認存儲在內存中.
  • executors:執行器,在定時任務執行時,以進程或線程方式執行
  • scheduler:調度器,包含BackgroundScheduler(后臺運行)和BlockingScheduler(阻塞運行).他會合理安排作業存儲器,執行器,觸發器進行工作.并進行添加和刪除任務等.調度器通常是只有一個的,開發人員很少直接操作觸發器,存儲器,執行器等.因為這些都由調度器自動來實現了.
5b1fb0c469726e3d0a8862ce1fd53d3a.png
10334

觸發器(triggers)

1.date在特定時間執行

示例:

from?datetime?import?date,?datetime

from?apscheduler.schedulers.blocking?import?BlockingScheduler


sched?=?BlockingScheduler()

def?my_job(text):
???print(text)

#?run_date?接受?date,?datetime?數據類型
sched.add_job(my_job,?'date',?run_date=datetime(2020,?11,?27,?19,?33,?30),?args=['text'])

sched.start()

更多:https://apscheduler.readthedocs.io/en/stable/modules/triggers/date.html

2.interval間隔執行

在固定的時間間隔后觸發事件.參數如下:

weeks周,整形
days一個月中的第幾天,整形
hours時,整形
minutes分,整形
seconds秒,整形
start_date起始時間
end_date結束時間
jitter觸發的時間誤差
from?apscheduler.schedulers.blocking?import?BlockingScheduler
from?datetime?import?datetime


sched?=?BlockingScheduler()

def?job_funciton():
???print('hello?world')


sched.add_job(job_funciton,?trigger='interval',seconds=5)
#?指定小時
#?sched.add_job(job_funciton,?trigger='interval',?hours=2)
#?指定開始,結束時間
#?sched.add_job(job_funciton,?trigger='interval',?start_date='2020-11-27?20:30:00',?end_date='2010-11-27?21:30:00)
sched.start()?

3.crontab

在某個確切的時間周期性觸發事件.

yearmonth1-12day1-31
week1-53day_of_week一周中的第幾天(0/Monday)hour0-23
minute0-59second0-59start_datedatetime數據類型,或者字符串類型
end_date結束時間timezone時區jitter觸發的誤差時間

也可以用表達式類型,可以用以下方式:

表達式字段描述
*任何在每個值都觸發
*/a任何每隔 a觸發一次
a-b任何在 a-b區間內任何一個時間觸發( a必須小于 b)
a-b/c任何在 a-b區間內每隔 c觸發一次
xth yday第 x個星期 y觸發
lastxday最后一個星期 x觸發
lastday一個月中的最后一天觸發
x,y,z任何可以把上面的表達式進行組合
from?apscheduler.schedulers.blocking?import?BlockingScheduler


def?job_function():
???print?"Hello?World"

sched?=?BlockingScheduler()

#?Schedules?job_function?to?be?run?on?the?third?Friday
#?of?June,?July,?August,?November?and?December?at?00:00,?01:00,?02:00?and?03:00
sched.add_job(job_function,?'cron',?month='6-8,11-12',?day='3rd?fri',?hour='0-3')

sched.start()

調度器(schedulers)

  1. BlockingScheduler:適用于調度程序是進程中唯一運行的進程,調用 start函數會阻塞當前線程,不能立即返回。
  2. BackgroundScheduler:適用于調度程序在應用程序的后臺運行,調用 start后主線程不會阻塞。
  3. AsyncIOScheduler:適用于使用了 asyncio模塊的應用程序。
  4. GeventScheduler:適用于使用 gevent模塊的應用程序。
  5. TwistedScheduler:適用于構建 Twisted的應用程序。
  6. QtScheduler:適用于構建 Qt的應用程序。
  7. TornadoScheduler: tornado

任務存儲器(job stores)

有2中方式,一種是加載在內存中(默認配置),一種是使用數據庫.使用內存簡單高效,但是程序出現問題,從新運行,會把以前的任務從新再執行一次.數據庫則可以在中斷的地方恢復正常使用.

  • MemoryJobStore:使用內存
  • MongoDBJobStore:使用mongodb
  • RedisJobStore:使用redis
  • SQLAlchemy:使用SQLAlchemy框架

1.RedisJobStore

RedisJobStore(db=0,?jobs_key='apscheduler.jobs',?run_times_key='apscheduler.run_times',?pickle_protocol=pickle.HIGHEST_PROTOCOL,?**connect_args)

有2種創建的方法:

  • add_jobstore:需要指定redis的相關參數.
from?datetime?import?datetime,?timedelta
import?sys
import?os

from?apscheduler.schedulers.blocking?import?BlockingScheduler
from?apscheduler.jobstores.redis?import?RedisJobStore



def?alarm(time):
????print('Alarm!?This?alarm?was?scheduled?at?%s.'?%?time)


if?__name__?==?'__main__':
????scheduler?=?BlockingScheduler()
????scheduler.add_jobstore('redis',?jobs_key='example.jobs',?run_times_key='example.run_times',?host='192.168.0.101',?port=6379,?db=0)
????if?len(sys.argv)?>?1?and?sys.argv[1]?==?'--clear':
????????scheduler.remove_all_jobs()

????alarm_time?=?datetime.now()?+?timedelta(seconds=300)
????scheduler.add_job(alarm,?'date',?run_date=alarm_time,?args=[datetime.now()])
????print('To?clear?the?alarms,?run?this?example?with?the?--clear?argument.')
????print('Press?Ctrl+{0}?to?exit'.format('Break'?if?os.name?==?'nt'?else?'C'))

????try:
????????scheduler.start()
????except?(KeyboardInterrupt,?SystemExit):
????????pass
  • RedisJobStore
from?apscheduler.schedulers.blocking?import?BlockingScheduler
from?apscheduler.jobstores.redis?import?RedisJobStore
from?datetime?import?datetime,?timedelta

jobstore?=?{
????'default'?:?RedisJobStore(db=0,?jobs_key='myfunc',?run_times_key='myfunc_time',?host='192.168.0.101',?port=6379)
}

def?my_func(t):
????print('hello?world,?%s'?%t)


if?__name__?==?'__main__':
????sched?=?BlockingScheduler(jobstores=jobstore)
????alarm_time?=?datetime.now()?+?timedelta(seconds=300)
????sched.add_job(my_func,run_date=alarm_time,?args=['ning'])
????sched.start()

均可在redis中查詢到數據.

79962117df8c769278bfb582f072d93d.png

2.SQLAlchemy

使用ORM框架,演示使用MySql

from?apscheduler.schedulers.blocking?import?BlockingScheduler
from?datetime?import?datetime,?timedelta

def?my_func(t):
???print('hello?%s'?%t)

if?__name__?==?"__main__":
???sched?=?BlockingScheduler()
???url?=?'mysql+pymysql://root:2008.Cn123@192.168.0.101:3306/test'
???sched.add_jobstore('sqlalchemy',?url=url,tablename='api_job')

???alarm_time?=?datetime.now()?+?timedelta(seconds=300)
???sched.add_job(my_func,run_date=alarm_time,?args=['ning'])
???sched.start()

如果表不存在,會自動創建表.tablename用于指定表的名稱.

在數據庫中可以查看到表

select?*?from?api_job;
5a7f5459de518a1986ff343de0909352.png
10336

執行器executors

執行器取決于應用場景,默認是ThreadPoolExecutor,它可以滿足大部分需求.如果是CPU密集型計算,可以選擇ProcessPoolExecutor

class?apscheduler.executors.pool.ThreadPoolExecutor(max_workers=10)class?apscheduler.executors.pool.ProcessPoolExecutor(max_workers=10)
#?max_worker?指定最多使用線程/進程
from?apscheduler.schedulers.background?import?BackgroundScheduler
from?apscheduler.executors.pool?import?ThreadPoolExecutor

executors?=?{
???'default':?ThreadPoolExecutor(20),
}
conf?=?{?#?redis配置
???"host":127.0.0.1,
???"port":6379,
???"db":15,?#?連接15號數據庫
???"max_connections":10?#?redis最大支持300個連接數
}
scheduler?=?BackgroundScheduler(executors=executors)
scheduler.add_jobstore(jobstore='redis',?**conf)?#?添加任務持久化存儲方式,如果未安裝redis可省略此步驟

任務操作

  • add_job(func, id='xxx', args=None, kwargs=None)添加任務
#?添加任務func,?func參數可以使用?'可導入模塊:可調用對象'的方式引入,即可用模塊來引入
#??tree?-L?2
#├──?func
#│???├──?add_func.py
#│???├──?__init__.py
#└──?jobs.py
#?add_func.py
def?add(x,y):
????print(x+y)
????
#?jobs.py
from?apscheduler.schedulers.blocking?import?BlockingScheduler
from?func.add_func?import?add

shced?=?BlockingScheduler()


if?__name__?==?"__main__":
????shced.add_job('func.add_func:add',?args=[1,2],?id='job1')
????shced.start()???

除去使用add_job(),還可以使用裝飾器函數scheduled_job來添加任務.

  • remove_job(job_id):刪除任務,需要指定job_id
  • pause_job(job_id):暫停任務
  • resume_job(job_id):恢復任務
  • modify_job(job_id, **changes):修改任務屬性
  • print_jobs():作業信息
#?方法1
job?=?scheduler.add_job(myfunc,?'interval',?minutes=2)??#?添加任務
job.remove()??#?刪除任務
job.pause()?#?暫定任務
job.resume()??#?恢復任務

#?方法2
scheduler.add_job(myfunc,?'interval',?minutes=2,?id='my_job_id')??#?添加任務????
scheduler.remove_job('my_job_id')??#?刪除任務
scheduler.pause_job('my_job_id')??#?暫定任務
scheduler.resume_job('my_job_id')??#?恢復任務

示例

方法1

from?pytz?import?utc
from?datetime?import?datetime
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
def?tick():
???print('Tick!?The?time?is:?%s'?%?datetime.now())
#?選擇MongoDB作為任務存儲數據庫
jobstores?=?{
???'mongo':?MongoDBJobStore(),
???'default':?SQLAlchemyJobStore(url='sqlite:///jobs.sqlite')
}
#?默認使用線程池
executors?=?{
???'default':?ThreadPoolExecutor(20),
???'processpool':?ProcessPoolExecutor(5)
}
#?默認參數配置
job_defaults?=?{
???'coalesce':?False,??#?積攢的任務是否只跑一次,是否合并所有錯過的Job
???'max_instances':?3,??#?默認同一時刻只能有一個實例運行,通過max_instances=3修改為3個。
???'misfire_grace_time':?30??#?30秒的任務超時容錯
}
scheduler?=?BackgroundScheduler(jobstores=jobstores,?executors=executors,?job_defaults=job_defaults,?timezone=utc)
scheduler.add_job(tick,?'interval',?seconds=3)
scheduler.start()

方法2

from?apscheduler.schedulers.background?import?BackgroundScheduler
#?The?"apscheduler."?prefix?is?hard?coded
scheduler?=?BackgroundScheduler({
???'apscheduler.jobstores.mongo':?{
????????'type':?'mongodb'
???},
???'apscheduler.jobstores.default':?{
???????'type':?'sqlalchemy',
???????'url':?'sqlite:///jobs.sqlite'
???},
???'apscheduler.executors.default':?{
???????'class':?'apscheduler.executors.pool:ThreadPoolExecutor',
???????'max_workers':?'20'
???},
???'apscheduler.executors.processpool':?{
???????'type':?'processpool',
???????'max_workers':?'5'
???},
???'apscheduler.job_defaults.coalesce':?'false',
???'apscheduler.job_defaults.max_instances':?'3',
???'apscheduler.timezone':?'UTC',
})

方法3

from?pytz?import?utc
from?apscheduler.schedulers.background?import?BackgroundScheduler
from?apscheduler.jobstores.sqlalchemy?import?SQLAlchemyJobStore
from?apscheduler.executors.pool?import?ProcessPoolExecutor
jobstores?=?{
???'mongo':?{'type':?'mongodb'},
???'default':?SQLAlchemyJobStore(url='sqlite:///jobs.sqlite')
}
executors?=?{
???'default':?{'type':?'threadpool',?'max_workers':?20},
???'processpool':?ProcessPoolExecutor(max_workers=5)
}
job_defaults?=?{
???'coalesce':?False,
???'max_instances':?3
}
scheduler?=?BackgroundScheduler()
#?..這里可以添加任務
scheduler.configure(jobstores=jobstores,?executors=executors,?job_defaults=job_defaults,?timezone=utc)

misfire_grace_time:如果一個job本來14:00有一次執行,但是由于某種原因沒有被調度上,現在14:01了,這個14:00的運行實例被提交時,會檢查它預訂運行的時間和當下時間的差值(這里是1分鐘),大于我們設置的30秒限制,那么這個運行實例不會被執行。合并:最常見的情形是scheduler被shutdown后重啟,某個任務會積攢了好幾次沒執行如5次,下次這個job被submit給executor時,執行5次。將coalesce=True后,只會執行一次

replace_existing: 如果在程序初始化時,是從數據庫讀取任務的,那么必須為每個任務定義一個明確的ID,并且使用replace_existing=True,否則每次重啟程序,你都會得到一份新的任務拷貝,也就意味著任務的狀態不會保存。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/533578.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/533578.shtml
英文地址,請注明出處:http://en.pswp.cn/news/533578.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

nginx php image,[Docker]應該把 nginx 和 PHP 放在一個 image 里還是分開?

因為老板想搞 K8S,但是我連 Docker 都不懂,就覺得還是要學一點點 Docker 的,之前還是看了一點點的,甚至折騰過一個開發環境的方案,但是,很長時間不弄了以后,就全都還回去了。這次我又想自己搭建…

python pep8模塊_讀懂PEP8,讓你的Python代碼更加優雅

PEP8《8 號 Python 增強規范》(Python Enhacement Proposal #8),簡稱PEP8通俗的來講 PEP8 是針對 python 代碼格式而編訂的風格指南,令代碼更加易讀易懂。像谷歌這樣的大公司是有自己內部的風格規范Google Style,目的就是為了提高開發效率。據…

python數值模擬教程_數值模擬必備random模塊

該模塊實現了各種分布的偽隨機數生成器。可以在區間內抽取一個隨機數,可以在列表中抽取一個元素,可以從分布中抽取樣本 。random模塊不能直接訪問,需要導入 random 模塊,然后通過 random 靜態對象調用該方法。import random1 生成…

php版本哪個沒有面向對象,php面向對象的方法重載兩種版本比較

多個函數用同一個名字,但參數表,即參數的個數或(和)數據類型可以不同,調用的時候,雖然方法名字相同,但根據參數表可以自動調用對應的函數。PHP4 中僅僅實現了面向對象的部分的、簡單的功能,而 PHP5 以后對對…

python實現錄音小程序 界面_小程序如何實現錄音 播放功能

第二步:編輯文件首先在src下創建一個test包并在test包下新建一個類MyRecord具體步驟代碼如下所示:package test;import java.awt.*;import javax.swing.*;import java.awt.event.*;import java.io.*;import javax.sound.sampled.*;public class MyRecord…

織夢php網站修改教程,織夢DEDEcms織夢軟件模型增加圖集功能教程(含修改文件下載)...

這篇文章主要為大家詳細介紹了織夢DEDEcms織夢軟件模型增加圖集功能教程(含修改文件下載),具有一定的參考價值,感興趣的小伙伴們可以參考一下,有需要的朋友可以收藏方便以后借鑒。織夢DEDEcms織夢軟件模型增加圖集功能,這是今天361模板要給大家分享的。下…

python自動截圖發送郵件_PhantomJS按尺寸截取頁面,并用python發送郵件

前言:當前有個任務是要把幾個網站的日志返回狀態碼進行匯總,用餅圖展示,并每天發送郵件。一、分析問題畫出餅圖,這個我用kibana給畫出來了,下面不做講解;截取餅圖,因為kibana是用js展示出來的&a…

nikita popov php,PHP中對performance的考慮點

Nikita Popov 在他的演講中談了幾個PHP 程序中和performance相關的point。1.PHP使用shared memory, preload的方式事先分配,而只有在所有的處理結束之后,share memory 才會斷開和所有進程或者thread之間的聯系。光是opcode,FPM的設定還不足以…

python建模仿真 matlab_清華大學出版社-圖書詳情-《仿真建模與MATLAB實用教程》

MATLAB語言是目前世界上最為流行的科學計算語言之一,它的特點是能夠快速地完成諸如矩陣運算、微分、尋優等計算任務。由于它配備了很多應用領域的專業工具箱,諸如金融、信號處理、圖像處理、神經網絡、嵌入式系統、仿真建模等,而且每個工具箱都包含了該應…

java web使用jquery,JAVA_Web_JQuery

簡介:jquery 全稱 javaScript Query.是js的一個框架。本質上仍然是js。特點:支持各種主流的瀏覽器、使用特別簡單、擁有便捷的插件擴展機制和豐富的插件。一、JQuery內部封裝原理介紹:匿名閉包。下面這兩行代碼是jquery包下的已經封裝的代碼&…

python語法學習_Python學習1——語法

Python語法包括了行、縮進、注釋、標識符、保留關鍵字等方面。打印語句:>>> print(hello,world!)hello,world!輸入語句:>>> input(請輸入你的名字:)請輸入你的名字:哈哈#”哈哈”是你自己輸入的名字哈哈 #打印出…

java 兩個頁面傳遞數據,請問Cookie怎么在兩個頁面間傳遞數據?

參考代碼如下://如果請求的Cookie對象為空if (Request.Cookies["userCookie"] null){//創建一個Cookie對象HttpCookie userCookie new HttpCookie("userCookie");//給對象賦值userCookie.Values["userName"] userInfo.UserName.ToS…

優化matlab作業,現代設計優化算法MATLAB實現

開篇語前陣子做現代設計方法的時候,發現網上很是缺乏這種作業形式的簡易算法實現,所以特地來簡書寫一篇。有兩份,一份是我的(說來慚愧,我的大部分都是在網上找的代碼,然后在自己的電腦上跑一次,跑出來了就行…

怎樣用python畫玫瑰花的簡筆畫_玫瑰花簡筆畫素描作品圖片

玫瑰原產是中國。在古時的漢語,“玫瑰”一詞原意是指紅色美玉。玫瑰花這么漂亮,素描怎么畫得好看呢?你知道玫瑰花的簡筆畫素描是怎樣的嗎?今天先和學習啦小編一起欣賞這些玫瑰花簡筆畫素描圖片,希望你會有所收獲的。玫瑰花簡筆畫素描圖片欣…

多因子選選股MATLAB代碼,金工研報:利用卷積神經網絡進行多因子選股

首先,我們先來看一下通過卷積神經網絡選股模型的整體流程,然后再根據每一步流程進行介紹,具體如下圖所示:1、數據獲取用于歷史回測數據來自所有A股股票,其中剔除了ST股以及上市3個月的股票,另外&#xff0c…

python list tuple 打包 解包_python的打包與解包

python的*與**,在函數的定義與調用過程中,有著不同的作用打包參數:一、函數定義時,形參前加*號(如:*args):收集實參中所有的位置參數,打包成新元組并將該元組賦值給args變量實參位置參數&#x…

python 成員函數 泛型函數_【一點資訊】白學這么多年 Python?連泛型函數都不會寫? www.yidianzixun.com...

泛型,如果你嘗過java,應該對他不陌生吧。但你可能不知道在 Python 中(3.4 ),也可以實現 簡單的泛型函數。在Python中只能實現基于單個(第一個)參數的數據類型來選擇具體的實現方式,官方名稱 是single-dispatch。你或許聽不懂&…

matlab bad apple,【bad apple】matlab制作矩陣蘋果~

有屏幕的地方就有bad apple那么作為一名工科生,熟練的操♂作馬桶蘿卜(matlab)是一項基本技能下面開始講解如何用matlab制作別具一格的“矩陣蘋果”~實驗環境matlab R2018a原版bad apple視頻技術要求可以即時演算圖形可以將處理后的每幀圖形合并成新的視頻先上代碼%t…

服務器ip直接訪問php怎么寫,php - 如何實現用公網ip訪問到服務器上的網頁?

服務器系統是Windows Server 2012 R2,已經部署了IIS、PHP和MySQL,能夠在云服務器上通過localhost打開php網頁,(放在服務器wwwroot上的index.php)已在ISS管理器中添加網站,但編輯網站綁定時,在ip地址中填入了服務器的公…

vb6 打印選項對話框_圖紙打印次數太多,不知道哪次才是最新的?用打印戳記區分效果好...

原創:就說我在開發區使用AutoCAD從事設計工作的朋友們不知道有沒遇到過這種情況:圖紙在反復修改打印的過程中,由于圖紙內容高度相似,往往搞不清究竟哪個才是最新版本的圖紙了。這種情況下,細致入微地去核對非常麻煩&am…