Celery-周期性任務


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_TZDjango 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

    位置參數(listtuple)。

  • 誇格

    關鍵字參數(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數據庫中,並提供一個方便的管理界面來在運行時管理定期任務。

要安裝和使用此擴展:

  1. 使用pip安裝軟件包:

    $ pip install django-celery-beat
    
  2. django_celery_beat模塊添加到INSTALLED_APPSDjango項目中settings.py

    INSTALLED_APPS = (
        ...,
        'django_celery_beat',
    )
    

    請注意,模塊名稱中沒有短划線,只有下划線。

  3. 應用Django數據庫遷移,以便創建必要的表:

    $ python manage.py migrate
    
  4. 使用調度程序啟動celery beat服務django_celery_beat.schedulers:DatabaseScheduler

    $ celery -A proj beat -l info --scheduler django_celery_beat.schedulers:DatabaseScheduler
    

    注意:您也可以beat_scheduler直接將其添加為設置。

  5. 訪問Django-Admin界面以設置一些定期任務。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM