Celery訊息佇列----配置定時任務
介紹
celery 定時器是一個排程器(scheduler);它會定時地開啟(kicks off)任務,然後由叢集中可用的工人(worker)來執行。
定時任務記錄(entries)預設 從 beat_schedule 設定中獲取,但自定義儲存也可以使用,如把記錄儲存到SQL資料庫中。
要確保同一時間一份時間表上只有一個排程器在執行,否則會因為重複傳送任務而結束。使用集中途徑意味著定時任務不用必須同步,並且服務無需用鎖操控。
記錄
為了定時呼叫任務,你必須新增記錄到打點列表中:
from celery import Celery
from celery.schedules import crontab
app = Celery()
@app.on_after_configure.connect
def setup_periodic_tasks(sender, **kwargs):
# 每10秒呼叫 test('hello') .
sender.add_periodic_task(10.0, test.s('hello'), name='add every 10')
# 每30秒呼叫 test('world')
sender.add_periodic_task(30.0, test.s('world'), expires=10)
# 每週一上午7:30執行
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()時我們不會在模組層面執行app 。
add_periodic_task() 函式在幕後會新增記錄到beat_schedule設定,同樣的設定可以用來手動設定定時任務:
例子: 每30秒執行 tasks.add .
app.conf.beat_schedule = {
'add-every-30-seconds': {
'task': 'tasks.add',
'schedule': 30.0,
'args': (16, 16)
},
}
app.conf.timezone = 'UTC'
一般會使用配置檔案進行配置,如下
celeryconfig.py:
broker_url = 'pyamqp://'
result_backend = 'rpc://'
task_serializer = 'json'
result_serializer = 'json'
accept_content = ['json']
timezone = 'Europe/Oslo'
enable_utc = True
beat_schedule = {
'add-every-30-seconds': {
'task': 'tasks.add',
'schedule': 30.0,
'args': (16, 16)
},
}
程式裡使用:
app.config_from_object('celeryconfig')
注意
如果你的引數元組裡只有一個專案,只用一個逗號就可以了,不要圓括號。
時間表使用時間差意味著每30秒間隔會發送任務(第一個任務在celery定時器開啟後30秒傳送,然後上每次距一次執行後30秒傳送一次)
可使用的屬性
task
要執行的任務名字
schedule
執行的頻率
可以是整數秒數,時間差,或者一個週期( crontab)。你也可以自 定義你的時間表型別,通過擴充套件schedule介面。
args
位置引數 (list 或 tuple).
kwargs
鍵值引數 (dict).
options
執行選項 (dict).
這可以是任何被apply_async()支援的引數與—-exchange, routing_key, expires,等。
relative
如果 relative 是 true ,時間表“由時鐘時間”安排,意味著 頻率近似到最近的秒,分鐘,小時或天,這取決於時間差中的時間間隔。
預設relative是false,頻率不會近似,會相對於celery的啟動時間。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’) | 每10分鐘執行,僅限於週六日3-4 am, 5-6 pm, and 10-11 pm |
crontab(minute=0, hour=’/2,/3’) | 偶數小時或者能被3整除的小時數執行 |
crontab(minute=0, hour=’*/5’) | 被5整除的小時數,如3pm |
crontab(minute=0, hour=’*/3,8-17’) | 8am-5pm能被3整除的 |
crontab(0, 0, day_of_month=’2’) | 每月第2天 |
crontab(0, 0,day_of_month=’2-30/3’) | 每偶數天 |
crontab(0, 0,day_of_month=’1-7,15-21’) | 每月1和3周 |
crontab(0, 0, day_of_month=’11’,month_of_year=’5’) | 每年5月11日 |
crontab(0, 0,month_of_year=’*/3’) | 每個季度第1月 |
開啟排程
開啟celery定時服務:
$ celery -A proj beat
你也可以把定時器嵌入到工人(worker)中,通過啟用workers -B選項,如果你永遠不會執行超過一個工人節點這就會很方便。但這不太常見,不推薦在生產環境這樣使用:
$ celery -A proj worker -B
定時器需要在本地資料庫檔案(預設名為 celerybeat-schedule )儲存任務上次執行時間,所以它需要在當前目錄中寫許可權。或者你也可以給這個檔案指定一個位置:
$ celery -A proj beat -s /home/celery/var/run/celerybeat-schedule