您好,登錄后才能下訂單哦!
Django中怎么利用Celery設(shè)置定時任務(wù),相信很多沒有經(jīng)驗的人對此束手無策,為此本文總結(jié)了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個問題。
Celery除了可以異步執(zhí)行任務(wù)之外,還可以定時執(zhí)行任務(wù)。在實例代碼的基礎(chǔ)上寫個測試方法:
#coding:utf-8from celery.task.schedules import crontab from celery.decorators import periodic_task @periodic_task(run_every=crontab())def some_task(): print('periodic task test!!!!!') time.sleep(5) print('success') return True
該代碼是每分鐘執(zhí)行一次some_task方法。
上篇文章啟動celery是使用worker。但worker不能啟動定時任務(wù)。啟動方式如下:
1)先確保中間人是否打開,我使用redis作為中間人??蓞⒖糝edis在CentOS和Windows安裝過程。
2)進(jìn)入django項目的根目錄執(zhí)行如下代碼啟動celery的worker:
有兩個任務(wù),其中一個myapp.tasks.sendmail是上篇文章添加的異步處理任務(wù)。myapp.tasks.some_task是本次的定時任務(wù)。
3)同樣在django項目的根目錄下再打開一個命令行界面,執(zhí)行如下代碼:
若你覺得1分鐘等待時間太長。可以設(shè)置為每10秒執(zhí)行一次定時任務(wù)。將上面的periodic_task修改如下:
@periodic_task(run_every=10)
修改代碼,需要重啟Celery的worker和beat。
這個run_every參數(shù)是設(shè)置定時任務(wù)的時間間隔或執(zhí)行的時間。該參數(shù)設(shè)置有3種方式。
1)直接設(shè)置秒數(shù)
例如剛剛所說的10秒間隔,run_every=10,每10秒執(zhí)行一次任務(wù)。1分鐘即是60秒;1小時即是3600秒。
2)通過datetime設(shè)置時間間隔
有時直接設(shè)置秒數(shù)不方便,需要通過計算得到具體秒數(shù)。
例如,1小時15分鐘40秒 = 1*60*60 + 15*60 + 40。這種情況可讀性也不高。
可以采用datetime設(shè)置,代碼如下:
from celery.decorators import periodic_taskimport datetime @periodic_task(run_every=datetime.timedelta(hours=1, minutes=15, seconds=40))def some_task(): print('periodic task test!!!!!')
代碼可讀性明顯提升,而且設(shè)置方便。
但這種不能滿足定時定點的時間設(shè)置。假如我想固定每天12點15分的時候,執(zhí)行一次任務(wù)。datetime和直接設(shè)置秒數(shù)的方式都無法實現(xiàn)。這時得使用第3種方式。
3)celery的crontab表達(dá)式
crontab是比較完善,且稍微有點復(fù)雜(相對前面兩種方式而言)的方式。可以實現(xiàn)我們各種設(shè)置時間的需求。
例如,前面給出的代碼:
#coding:utf-8from celery.task.schedules import crontab from celery.decorators import periodic_task @periodic_task(run_every=crontab())def some_task(): print('periodic task test!!!!!')
表示每分鐘0秒時刻執(zhí)行一次(后面不提這個0秒,大家都知道就行了,省點口水)。
其中,crontab()實例化的時候沒設(shè)置任何參數(shù),都是使用默認(rèn)值。crontab一共有7個參數(shù),常用有5個參數(shù)分別為:
minute:分鐘,范圍0-59;
hour:小時,范圍0-23;
day_of_week:星期幾,范圍0-6。以星期天為開始,即0為星期天。這個星期幾還可以使用英文縮寫表示,例如“sun”表示星期天;
day_of_month:每月第幾號,范圍1-31;
month_of_year:月份,范圍1-12。
a、默認(rèn)參數(shù)
這些參數(shù)可以設(shè)置表達(dá)式,表達(dá)稍微復(fù)雜的設(shè)置。默認(rèn)值都是"*"星號,代表任意時刻。即crontab()相當(dāng)與:
crontab(minute='*', hour='*', day_of_week='*', day_of_month='*', month_of_year='*')
含義是每天、每小時、每分鐘執(zhí)行一次任務(wù)。這說法太反人類語言習(xí)慣,簡單說就是每1分鐘執(zhí)行一次任務(wù)。
b、具體某個值
上面提到這些參數(shù)的取值范圍。我們可以直接設(shè)置某個值。例如:
crontab(minute=15)
即每小時的15分時刻執(zhí)行一次任務(wù)。直接指定某個時刻。以此類推可以設(shè)置每天0點0分時刻執(zhí)行任務(wù)的設(shè)置如下:
crontab(minute=0, hour=0)
當(dāng)然,也可以設(shè)置多個值。例如0分和30分執(zhí)行一次任務(wù):
crontab(minute='0,30')
這里使用字符串,用逗號隔開數(shù)值。這里的逗號是表示多個表達(dá)式or邏輯關(guān)系。
c、設(shè)置范圍
設(shè)置范圍也是設(shè)置多個值,例如指定9點到12點每個小時的每分鐘執(zhí)行任務(wù)。
crontab(minute='*', hour='9-12')
這里*號是默認(rèn)值,可以省略如下:
crontab(hour='9-12')
上面提到逗號是or邏輯關(guān)系。拓展一下,指定9點到12點和20點中每分鐘執(zhí)行任務(wù):
crontab(hour='9-12,20')
crontab的表達(dá)式越來越復(fù)雜了。celery還提供了一個類得到表達(dá)式解析結(jié)果,代碼如下:
from celery.task.schedules import crontab_parserr = crontab_parser(23, 0).parse('9-12,20')print(r)
其中,crontab_parse是一個解析類。第1個參數(shù)是范圍的最大值;第2個參數(shù)是范圍的最小值。通過parse輸入表達(dá)式,可得到表達(dá)式的解析結(jié)果:
set([9, 10, 11, 12, 20])
下面很多地方我們都可以通過該方法驗證解析結(jié)果。
d、設(shè)置間隔步長
假如我要設(shè)置1、3、5、7、9、11月份每天每分鐘執(zhí)行任務(wù),按照上面的做法可以設(shè)置如下:
crontab(day_of_month='1,3,5,7,9,11')
觀察數(shù)據(jù)可以發(fā)現(xiàn),都是間隔2的步長。需要設(shè)置的數(shù)字比較少,若數(shù)字比較多顯得很麻煩。例如我想每間隔2分鐘就執(zhí)行一次任務(wù),要寫30個數(shù)字想想就覺得很麻煩。crontab表達(dá)式還提供了間隔的處理,例如:
crontab(minute='*/2')crontab(minute='0-59/2') #效果等同上面
這個/號不是除以的意思。相當(dāng)與range的第3個參數(shù),例如:
range(0, 59+1, 2)
差不多crontab表達(dá)式就這些,多舉幾個例子:
#每2個小時中每分鐘執(zhí)行1次任務(wù)crontab(hour='*/2') #每3個小時的0分時刻執(zhí)行1次任務(wù)#即[0,3,6,9,12,15,18,21]點0分crontab(minute=0, hour='*/3') #每3個小時或8點到12點的0分時刻執(zhí)行1次任務(wù)#即[0,3,6,9,12,15,18,21]+[8,9,10,11,12]點0分crontab(minute=0, hour='*/3,8-12') #每個季度的第1個月中,每天每分鐘執(zhí)行1次任務(wù)#月份范圍是1-12,每3個月為[1,4,7,10]crontab(month_of_year='*/3') #每月偶數(shù)天數(shù)的0點0分時刻執(zhí)行1次任務(wù)crontab(minute=0, hour=0, day_of_month='2-31/2') #每年5月11號的0點0分時刻執(zhí)行1次任務(wù)crontab(0, 0, day_of_month='11', month_of_year='5')
這些表達(dá)式設(shè)置都可以用crontab_parser驗證。
看完上述內(nèi)容,你們掌握Django中怎么利用Celery設(shè)置定時任務(wù)的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注億速云行業(yè)資訊頻道,感謝各位的閱讀!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。