1. 程式人生 > >Bamboo Django Celery定時任務和時間設定

Bamboo Django Celery定時任務和時間設定

1、Celery加入定時任務

Celery除了可以非同步執行任務之外,還可以定時執行任務。在例項程式碼的基礎上寫個測試方法:

複製程式碼
 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方法。

啟動celery是使用worker。但worker不能啟動定時任務。啟動方式如下:

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

 

2)進入django專案的根目錄執行如下程式碼啟動celery的worker:

1 celery -A myproject worker -l info

 

其中,myproject是我的django專案名稱。

當出現[email protected] ready說明redis啟動成功。

有兩個任務,其中一個myapp.tasks.sendmail新增的非同步處理任務。myapp.tasks.some_task是本次的定時任務。

 

3)同樣在django專案的根目錄下再開啟一個命令列介面,執行如下程式碼:

1 celery -A myproject beat -l info

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

可以稍微等待幾分鐘,多執行幾次任務。如下圖:

 

上面的視窗是beat,下面的視窗是worker。可看到print的資訊在worker中輸出。

我們甚至不用開啟Django專案的伺服器,就可以執行定時任務。 

2、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、設定間隔步長

假如我要設定1、3、5、7、9、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表示式就這些,多舉幾個例子:

按 Ctrl+C 複製程式碼 按 Ctrl+C 複製程式碼

 來自https://www.cnblogs.com/dengshihuang/p/8258621.html