Celery(4.4)的當前穩定版本。
官網文檔:https://docs.celeryproject.org/en/latest/index.html
周期性任務
簡介
celery beat是一個調度程序;它定期啟動任務,然后由集群中的可用工作程序節點執行任務。
默認情況下,條目是從beat_schedule
設置中獲取的,但也可以使用自定義存儲,例如將條目存儲在SQL數據庫中。
您必須確保一次只有一個調度程序針對一個調度程序運行,否則最終將導致重復的任務。使用集中式方法意味着時間表不必同步,並且服務可以在不使用鎖的情況下運行。
時區
默認情況下,定期任務計划使用UTC時區,但是您可以使用該timezone
設置更改使用的時區。
時區的示例可以是Europe / London:
timezone = 'Europe/London'
必須使用()直接對其進行配置,或者如果使用對其進行了設置,則必須將其添加到配置模塊中,才能 將該設置添加到您的應用中。有關配置選項的更多信息,請參見配置。app.conf.timezone = 'Europe/London'``app.config_from_object
默認的調度程序(將調度程序存儲在celerybeat-schedule
文件中)將自動檢測到時區已更改,因此將重置調度程序本身,但是其他調度程序可能不那么聰明(例如Django數據庫調度程序,請參見下文)。在這種情況下,您必須手動重置計划。
Django用戶
Celery建議並與USE_TZ
Django 1.4中引入的新設置兼容。
對於Django用戶,TIME_ZONE
將使用設置中指定的時區,或者您可以使用timezone
設置單獨為Celery指定自定義時區。
與時區相關的設置更改時,數據庫調度程序不會重置,因此您必須手動執行此操作:
$ python manage.py shell
>>> from djcelery.models import PeriodicTask
>>> PeriodicTask.objects.update(last_run_at=None)
Django-Celery僅支持Celery 4.0及更低版本,對於Celery 4.0及更高版本,請執行以下操作:
$ python manage.py shell
>>> from django_celery_beat.models import PeriodicTask
>>> PeriodicTask.objects.update(last_run_at=None)
條目
要定期調用任務,您必須在拍子時間表列表中添加一個條目。
from celery import Celery
from celery.schedules import crontab
app = Celery()
@app.on_after_configure.connect
def setup_periodic_tasks(sender, **kwargs):
# Calls test('hello') every 10 seconds.
sender.add_periodic_task(10.0, test.s('hello'), name='add every 10')
# Calls test('world') every 30 seconds
sender.add_periodic_task(30.0, test.s('world'), expires=10)
# Executes every Monday morning at 7:30 a.m.
sender.add_periodic_task(
crontab(hour=7, minute=30, day_of_week=1),
test.s('Happy Mondays!'),
)
@app.task
def test(arg):
print(arg)
在on_after_configure
處理程序中進行設置意味着使用時,我們不會在模塊級別評估應用test.s()
。請注意,該消息 on_after_configure
是在設置應用程序后發送的,因此在聲明應用程序的模塊之外的任務(例如在位於的task.py文件中 celery.Celery.autodiscover_tasks()
)必須使用更高的信號,例如 on_after_finalize
。
該add_periodic_task()
功能會將條目添加到beat_schedule
幕后的 設置中,並且相同的設置還可用於手動設置定期任務:
示例:每30秒運行task.add任務。
app.conf.beat_schedule = {
'add-every-30-seconds': {
'task': 'tasks.add',
'schedule': 30.0,
'args': (16, 16)
},
}
app.conf.timezone = 'UTC'
注意
如果您想知道這些設置應該去哪里,請參閱配置。您可以直接在應用程序上設置這些選項,也可以保留單獨的模塊進行配置。
如果要對args使用單個項目元組,請不要忘記構造函數是逗號,而不是一對括號。
timedelta
對時間表使用a 表示任務將以30秒為間隔發送(第一個任務將在開始芹菜拍打 30秒后發送,然后在最后一次運行之后每30秒發送一次)。
還存在類似Crontab的日程表,請參閱有關Crontab日程表的部分。
與cron一樣,如果第一個任務在下一個任務之前沒有完成,則這些任務可能會重疊。如果這是一個問題,則應該使用鎖定策略來確保一次只能運行一個實例(例如, 確保確保一次僅執行一個任務)。
可用字段
-
任務
要執行的任務的名稱。
-
時間表
執行頻率。
這可以是整數,a
timedelta
或a 的秒數crontab
。您還可以通過擴展的界面來定義自己的自定義計划類型schedule
。 -
args
-
誇格
關鍵字參數(
dict
)。 -
選項
執行選項(
dict
)。這可以是
apply_async()
– exchange,routing_key,expires等支持的任何參數 。 -
相對的
如果相對是真的,
timedelta
時間表是“按時”安排的。這意味着頻率會根據的時間舍入到最接近的秒,分鍾,小時或天timedelta
。默認情況下,relative為false,頻率不四舍五入,將與開始芹菜拍打的時間有關。
Crontab時間表
如果要對執行任務的時間(例如,一天中的特定時間或一周中的一天)進行更多控制,則可以使用crontab
計划類型:
from celery.schedules import crontab
app.conf.beat_schedule = {
# Executes every Monday morning at 7:30 a.m.
'add-every-monday-morning': {
'task': 'tasks.add',
'schedule': crontab(hour=7, minute=30, day_of_week=1),
'args': (16, 16),
},
}
這些Crontab表達式的語法非常靈活。
一些例子:
例 | 含義 |
---|---|
crontab() |
每分鍾執行一次。 |
crontab(minute=0, hour=0) |
每天午夜執行。 |
crontab(minute=0, hour='*/3') |
每三個小時執行一次:午夜,3am,6am,9am,中午,3pm,6pm,9pm。 |
crontab(minute=0,``hour='0,3,6,9,12,15,18,21') |
和以前一樣。 |
crontab(minute='*/15') |
每15分鍾執行一次。 |
crontab(day_of_week='sunday') |
在星期日執行每一分鍾(!)。 |
crontab(minute='*',``hour='*', day_of_week='sun') |
和以前一樣。 |
crontab(minute='*/10',``hour='3,17,22', day_of_week='thu,fri') |
每十分鍾執行一次,但僅在周四或周五的凌晨3-4點,下午5-6點以及晚上10-11點之間執行。 |
crontab(minute=0, hour='*/2,*/3') |
每隔一小時執行一次,每一小時被三整除。這意味着:每小時除外:1 am、5am、7am、11am、1pm、5pm、7pm、11pm |
crontab(minute=0, hour='*/5') |
執行小時可被5整除。這意味着它在下午3點而不是下午5點被觸發(因為3pm等於24小時制時鍾值“ 15”,可被5整除)。 |
crontab(minute=0, hour='*/3,8-17') |
每小時執行一次可被3整除的時間,並在辦公時間(上午8點至下午5點)每小時執行一次。 |
crontab(0, 0, day_of_month='2') |
在每個月的第二天執行。 |
crontab(0, 0,``day_of_month='2-30/2') |
在每個偶數天執行一次。 |
crontab(0, 0,``day_of_month='1-7,15-21') |
在每月的第一和第三周執行。 |
crontab(0, 0, day_of_month='11',``month_of_year='5') |
每年5月11日執行。 |
crontab(0, 0,``month_of_year='*/3') |
在每個季度的第一個月每天執行一次。 |
請參閱celery.schedules.crontab
以獲取更多文檔。
太陽能時間表
如果您有應根據日出,日落,黎明或黃昏執行的任務,則可以使用 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)
確保對緯度和經度使用正確的符號:
標志 | 爭論 | 含義 |
---|---|---|
+ |
latitude |
北 |
- |
latitude |
南 |
+ |
longitude |
東 |
- |
longitude |
西方 |
可能的事件類型是:
事件 | 含義 |
---|---|
dawn_astronomical |
在天空不再完全黑暗的那一刻執行。這是當太陽低於地平線18度時。 |
dawn_nautical |
當有足夠的陽光照亮地平線並區分一些物體時執行。正式地,當太陽低於地平線12度時。 |
dawn_civil |
當有足夠的光線可辨別物體時執行,以便戶外活動可以開始;正式地,當太陽在地平線以下6度時。 |
sunrise |
當早晨早晨太陽的上邊緣出現在東部地平線上方時執行。 |
solar_noon |
當當天太陽最高到地平線以上時執行。 |
sunset |
當傍晚太陽的后緣在西方地平線上消失時執行。 |
dusk_civil |
當物體仍然可以區分並且可見一些恆星和行星時,在民航末尾執行。正式地,當太陽低於地平線6度時。 |
dusk_nautical |
當太陽低於地平線12度時執行。物體不再可分辨,並且肉眼不再看到地平線。 |
dusk_astronomical |
在天空完全變暗的那一刻執行;正式地,當太陽低於地平線18度時。 |
所有太陽事件都是使用UTC計算的,因此不受時區設置的影響。
在極地地區,太陽不一定每天都會升起或落下。調度程序能夠處理這些情況(即,sunrise
在太陽不升起的一天不會發生事件)。一個例外是solar_noon
,正式定義為太陽經過天子午線的那一刻,即使太陽在地平線以下,它也會每天發生。
暮光定義為黎明到日出之間的時間;在日落和黃昏之間。您可以使用上面列表中的適當事件,根據您對暮光的定義(民用,航海或天文),以及是否要在暮光的開始或結束時,根據“暮光”安排事件。 。
請參閱celery.schedules.solar
以獲取更多文檔。
啟動調度
要啟動celery beat服務:
$ celery -A proj beat
您也可以通過啟用workers 選項將beat嵌入到worker中,-B
如果您永遠不會運行一個以上的worker節點,這很方便,但是它並不常用,因此不建議用於生產環境:
$ celery -A proj worker -B
Beat需要將任務的最后運行時間存儲在本地數據庫文件(默認情況下命名為celerybeat-schedule)中,因此它需要訪問權限才能在當前目錄中進行寫操作,或者可以為此文件指定一個自定義位置:
$ celery -A proj beat -s /home/celery/var/run/celerybeat-schedule
注意
要守護節拍,請參見守護進程。
使用自定義調度類
可以在命令行(--scheduler
參數)上指定自定義調度程序類 。
默認調度程序是celery.beat.PersistentScheduler
,它僅跟蹤本地shelve
數據庫文件中的最后運行時間。
還有django-celery-beat擴展,可將日程表存儲在Django數據庫中,並提供一個方便的管理界面來在運行時管理定期任務。
要安裝和使用此擴展:
-
使用pip安裝軟件包:
$ pip install django-celery-beat
-
將
django_celery_beat
模塊添加到INSTALLED_APPS
Django項目中settings.py
:INSTALLED_APPS = ( ..., 'django_celery_beat', )
請注意,模塊名稱中沒有短划線,只有下划線。
-
應用Django數據庫遷移,以便創建必要的表:
$ python manage.py migrate
-
使用調度程序啟動celery beat服務
django_celery_beat.schedulers:DatabaseScheduler
:$ celery -A proj beat -l info --scheduler django_celery_beat.schedulers:DatabaseScheduler
注意:您也可以
beat_scheduler
直接將其添加為設置。 -
訪問Django-Admin界面以設置一些定期任務。