要定時或者周期性的執行任務,可以使用linux的crontab。Celery也提供了類似的Periodic Tasks功能。 Celery beat Celery使用celery beat作為任務調度器,周期性的啟動任務。 需要執行的任務預設是在beat_schedule配置選項中設置的。使用dja ...
要定時或者周期性的執行任務,可以使用linux的crontab。Celery也提供了類似的Periodic Tasks功能。
Celery beat
Celery使用celery beat作為任務調度器,周期性的啟動任務。
需要執行的任務預設是在beat_schedule配置選項中設置的。使用django-celery-beat時,也可以使用資料庫存儲。
需要保證同一時間只有一個任務調度器在運行,否則會重覆的執行任務。
Time Zones
既然是任務與時間有關,那麼時區設置是很重要的。Celery預設使用UTC時區,要改變預設時區,可以配置:
timezone = Asia/Shanghai'
在django項目中使用celery時,celery也可以使用setting的TIME_ZONE時區設置。
使用預設的任務調度器時,celery會自動識別時區的改動,然後重置任務調度。使用其它任務調度時,需要手動重置。
比如,使用django-celery-beat時:
$ python manage.py shell >>> from djcelery.models import PeriodicTask >>> PeriodicTask.objects.update(last_run_at=None)
Entries
要添加周期任務,需要將事務添加到任務調度器中,添加方法有兩種。
一種是使用add_periodic_task() 方法:
from __future__ import absolute_import, unicode_literals from celery.schedules import crontab from .celery import app @app.on_after_configure.connect def setup_periodic_tasks(sender, **kwargs): # Calls add(1, 2) every 10 seconds. sender.add_periodic_task(10.0, add.s(1, 2), name='add every 10') # Calls add(3, 4) every 30 seconds sender.add_periodic_task(30.0, add.s(3, 4), ) # Executes every Monday morning at 7:30 a.m. sender.add_periodic_task( ┆ crontab(hour=7, minute=30, day_of_week=1), ┆ add.s(1, 2), ) @app.task def add(x, y): print x + y return x + y
另一種方法是配置beat_schedule選項:
app.conf.beat_schedule = { 'add-every-30-seconds': { 'task': 'tasks.add', 'schedule': 30.0, 'args': (3, 4) }, }
可用欄位:
task:需要執行的任務名稱
schedule:任務執行時間設定,可以是整秒數,一個timedelta對象,或者一個crontab對象,也可以自己實現。
args:一個元組或者列表,位置參數
kwargs:一個字典,關鍵字參數
options:一個字典,一些額外選項,apply_async()方法可用的參數,exchange, routing_key, expires等
relative:預設false
Crontab
class celery.schedules.crontab(minute=u'*', hour=u'*', day_of_week=u'*', day_of_month=u'*', month_of_year=u'*', **kwargs)
一個表示時間間隔的對象,語法與linux的crontab類似。
minute和hour可以設置為*/15,*/2,分別表示每隔15分鐘和每隔2小時。
day_of_week用可以0-6的數字表示,也可以文字表示mon-fri。*/2並不是每2天,而是每半天。
官網一些具體例子:
crontab() 每分鐘
crontab(minute=0, hour=0) 每天的0時0分
crontab(minute=0, hour='*/3') 每三小時
crontab(day_of_week='sunday') 周日的每一小時
crontab(minute='*',hour='*', day_of_week='sun') 與上面相同
crontab(minute=0, hour='*/3,8-17') 每三個小時 8時到17時的每小時
Solar
可用日升日落表示的時間間隔:
from celery.schedules import solar app.conf.beat_schedule = { # Executes at sunset in Melbourne 'add-at-melbourne-sunset': { 'task': 'tasks.add', 'schedule': solar('sunset', -37.81753, 144.96715), 'args': (16, 16), }, }
語法是solar(event, latitude, longitude)
event表示日落日出,latitude為緯度,北緯為+,longitude為經度,東經為+。
啟動
啟動celery beat周期任務命令:
$ celery -A proj beat
然後啟動worker節點來處理任務即可。
beat與worker也可以同時啟動,但最好只用於測試,適用於只啟動一個worker節點的情況:
$ celery -A proj worker -B
beat會在當前目錄下建立一個文件celerybeat-schedule來記錄任務上次運行的時間,所以要保證celery對當前目錄有寫入的許可權,或者指定文件位置:
$ celery -A proj beat -s /home/celery/var/run/celerybeat-schedule