celery 定時任務時間篇

一、Celery加入定時任務html

Celery除了能夠異步執行任務以外,還能夠定時執行任務。在實例代碼的基礎上寫個測試方法:redis

複製代碼
複製代碼
 1 #coding:utf-8
 2 from celery.task.schedules import crontab 
 3 from celery.decorators import periodic_task
 4 
 5 @periodic_task(run_every=crontab())
 6 def some_task():
 7 print('periodic task test!!!!!')
 8 time.sleep(5)
 9 print('success')
10 return True
複製代碼
複製代碼

該代碼是每分鐘執行一次some_task方法。django

啓動celery是使用worker。但worker不能啓動定時任務。啓動方式以下:服務器

1)先確保中間人是否打開,我使用redis做爲中間人。可參考Redis在CentOS和Windows安裝過程app

 

2)進入django項目的根目錄執行以下代碼啓動celery的worker:異步

1 celery -A myproject worker -l info

 

其中,myproject是個人django項目名稱。測試

當出現celery@xxx ready說明redis啓動成功。spa

有兩個任務,其中一個myapp.tasks.sendmail添加的異步處理任務。myapp.tasks.some_task是本次的定時任務。命令行

 

3)一樣在django項目的根目錄下再打開一個命令行界面,執行以下代碼:code

1 celery -A myproject beat -l info

這個beat是檢查定時任務,並啓動定時任務丟給worker執行。

能夠稍微等待幾分鐘,多執行幾回任務。以下圖:

 

上面的窗口是beat,下面的窗口是worker。可看到print的信息在worker中輸出。

咱們甚至不用打開Django項目的服務器,就能夠執行定時任務。 

二、Celery定時任務時間設置

若你以爲1分鐘等待時間太長。能夠設置爲每10秒執行一次定時任務。將上面的periodic_task修改以下:

1 @periodic_task(run_every=10)

修改代碼,須要重啓Celery的worker和beat。

這個run_every參數是設置定時任務的時間間隔或執行的時間。該參數設置有3種方式。

1)直接設置秒數

例如剛剛所說的10秒間隔,run_every=10,每10秒執行一次任務。1分鐘便是60秒;1小時便是3600秒。

 

2)經過datetime設置時間間隔

有時直接設置秒數不方便,須要經過計算獲得具體秒數。

例如,1小時15分鐘40秒 = 1*60*60 + 15*60 + 40。這種狀況可讀性也不高。

能夠採用datetime設置,代碼以下:

1 from celery.decorators import periodic_task
2 import datetime
3 
4 @periodic_task(run_every=datetime.timedelta(hours=1, minutes=15, seconds=40))
5 def some_task():
6 print('periodic task test!!!!!')

代碼可讀性明顯提高,並且設置方便。

但這種不能知足定時定點的時間設置。假如我想固定天天12點15分的時候,執行一次任務。datetime和直接設置秒數的方式都沒法實現。這時得使用第3種方式。

 

3)celery的crontab表達式

crontab是比較完善,且稍微有點複雜(相對前面兩種方式而言)的方式。能夠實現咱們各類設置時間的需求。

例如,前面給出的代碼:

複製代碼
複製代碼
1 #coding:utf-8
2 from celery.task.schedules import crontab 
3 from celery.decorators import periodic_task
4 
5 @periodic_task(run_every=crontab())
6 def some_task():
7 print('periodic task test!!!!!') 
複製代碼
複製代碼

表示每分鐘0秒時刻執行一次(後面不提這個0秒,你們都知道就好了,省點口水)。

其中,crontab()實例化的時候沒設置任何參數,都是使用默認值。crontab一共有7個參數,經常使用有5個參數分別爲:

minute:分鐘,範圍0-59;

hour:小時,範圍0-23;

day_of_week:星期幾,範圍0-6。以星期天爲開始,即0爲星期天。這個星期幾還可使用英文縮寫表示,例如「sun」表示星期天;

day_of_month:每個月第幾號,範圍1-31;

month_of_year:月份,範圍1-12。

 

a、默認參數

這些參數能夠設置表達式,表達稍微複雜的設置。默認值都是"*"星號,表明任意時刻。即crontab()至關與:

1 crontab(minute='*', hour='*', day_of_week='*', day_of_month='*', month_of_year='*')

含義是天天、每小時、每分鐘執行一次任務。這說法太反人類語言習慣,簡單說就是每1分鐘執行一次任務。

 

b、具體某個值

上面提到這些參數的取值範圍。咱們能夠直接設置某個值。例如:

1 crontab(minute=15)

即每小時的15分時刻執行一次任務。直接指定某個時刻。以此類推能夠設置天天0點0分時刻執行任務的設置以下:

1 crontab(minute=0, hour=0)

固然,也能夠設置多個值。例如0分和30分執行一次任務:

crontab(minute='0,30')

這裏使用字符串,用逗號隔開數值。這裏的逗號是表示多個表達式or邏輯關係。

 

c、設置範圍

設置範圍也是設置多個值,例如指定9點到12點每一個小時的每分鐘執行任務。

1 crontab(minute='*', hour='9-12')

這裏*號是默認值,能夠省略以下:

1 crontab(hour='9-12')

上面提到逗號是or邏輯關係。拓展一下,指定9點到12點和20點中每分鐘執行任務:

1 crontab(hour='9-12,20')

crontab的表達式愈來愈複雜了。celery還提供了一個類獲得表達式解析結果,代碼以下:

1 from celery.task.schedules import crontab_parser
2 r = crontab_parser(23, 0).parse('9-12,20')
3 print(r)

其中,crontab_parse是一個解析類。第1個參數是範圍的最大值;第2個參數是範圍的最小值。經過parse輸入表達式,可獲得表達式的解析結果:

1 set([9, 10, 11, 12, 20])

下面不少地方咱們均可以經過該方法驗證解析結果。

  

d、設置間隔步長

假如我要設置一、三、五、七、九、11月份天天每分鐘執行任務,按照上面的作法能夠設置以下:

1 crontab(day_of_month='1,3,5,7,9,11')

觀察數據能夠發現,都是間隔2的步長。須要設置的數字比較少,若數字比較多顯得很麻煩。例如我想每間隔2分鐘就執行一次任務,要寫30個數字想一想就以爲很麻煩。crontab表達式還提供了間隔的處理,例如:

1 crontab(minute='*/2')
2 crontab(minute='0-59/2') #效果等同上面

這個/號不是除以的意思。至關與range的第3個參數,例如:

1 range(0, 59+1, 2)

差很少crontab表達式就這些,多舉幾個例子:

複製代碼
複製代碼
 1 #每2個小時中每分鐘執行1次任務
 2 crontab(hour='*/2')
 3 
 4 #每3個小時的0分時刻執行1次任務
 5 #即[0,3,6,9,12,15,18,21]點0分
 6 crontab(minute=0, hour='*/3')
 7 
 8 #每3個小時或8點到12點的0分時刻執行1次任務
 9 #即[0,3,6,9,12,15,18,21]+[8,9,10,11,12]點0分
10 crontab(minute=0, hour='*/3,8-12')
11 
12 #每一個季度的第1個月中,天天每分鐘執行1次任務
13 #月份範圍是1-12,每3個月爲[1,4,7,10]
14 crontab(month_of_year='*/3')
15 
16 #每個月偶數天數的0點0分時刻執行1次任務
17 crontab(minute=0, hour=0, day_of_month='2-31/2')
18 
19 #每一年5月11號的0點0分時刻執行1次任務
20 crontab(0, 0, day_of_month='11', month_of_year='5')
複製代碼
複製代碼
相關文章
相關標籤/搜索