淺談celery的坑

celery

celery的使用以及在Django中的配置,不詳細介紹,主要記錄在Django中使用的坑點。html

坑點

時區問題

celery默認的時區是世界標準時間,比東八區慢了8個小時,若是發佈定時任務,必定要注意定時的時間,不然可能用了正確的方法,可是並無調用成功python

設置celery的時區能夠在Django項目的settings.py中添加一條設置shell

CELERY_TIMEZONE = 'Asia/Shanghai'
複製代碼

django-celery能夠識別在設置中的時區django

也能夠在發佈定時任務的時候,指定到當前的時區,使用Django自帶的get_current_timezone()json

# 將須要設定的時間轉換成當前時區的時間
from django.utils.timezone import get_current_timezone
import datetime

send_time = datetime.datetime.now() + datetime.timedelta(days=1)
tz = get_current_timezone()
send_time = tz.localize(send_time)
複製代碼

在使用異步任務的時候將轉換後的時間傳入到參數裏面app

celery_task.apply_async(args=[], kwdg={}, eta=send_time)
複製代碼

固然,你也可使用間隔時間執行異步任務,對應apply_async()裏面的countdown參數異步

celery_task.apply_async(countdown=seconds)
複製代碼

celery的序列化問題

celery提供了兩個序列化的格式,picklejson,pickle是python一個序列化的庫,能夠實現多種格式數據的序列和反序列化,對應pickle和unpickleasync

設置中能夠指定celery接受的數據格式,以及任務和結果的序列化器spa

# settings.py
# celery容許接收的數據格式,能夠是一個字符串,好比'json'
CELERY_ACCEPT_CONTENT = ['pickle', 'json']
# 異步任務的序列化器,也能夠是json
CELERY_TASK_SERIALIZER = 'pickle'
# 任務結果的數據格式,也能夠是json
CELERY_RESULT_SERIALIZER = 'pickle'
複製代碼

在Django中的使用尤爲須要注意,若是你須要向異步任務傳入一個queryset,須要將接收的格式和序列化器設置爲'pickle',即如上設置code

不建議將ORM對象傳給celery的異步任務,拿到的多是過時數據,建議傳遞id

結果

若是不須要講異步任務執行的結果進行處理,即異步任務的執行結果和業務邏輯關係不大,建議不存儲celery異步任務的結果。

若是保留結果,celery將會爲任務結果創建一個隊列,而且一直等到異步任務給出結果纔會將任務從隊列中刪除,建立和管理任務的開銷很大,能夠在這篇博客中看到:www.cnblogs.com/blaketairan…

在Django的settings中設置忽略celery任務執行結果

CELERY_IGNORE_RESULT = True
複製代碼

使用不一樣的queue

若是任務A比任務B更重要,而任務B的量很是大,重要的任務A就須要不斷等待任務B完成後才能繼續進行,這時候,可使用不一樣的queue來保存任務,讓不一樣的worker來執行兩種任務

CELERY_QUEUES = (
    Queue('default', Exchange('default'), routing_key='default'),
    Queue('for_task_A', Exchange('for_task_A'), routing_key='for_task_A'),
    Queue('for_task_B', Exchange('for_task_B'), routing_key='for_task_B'),
)
複製代碼

而後自定義router來執行不一樣的任務

CELERY_ROUTES = {
    'my_taskA': {'queue': 'for_task_A', 'routing_key': 'for_task_A'},
    'my_taskB': {'queue': 'for_task_B', 'routing_key': 'for_task_B'},
}
複製代碼

而後在啓動celery時,指定不一樣的worker

celery worker -E -l INFO -n workerA -Q for_task_A celery worker -E -l INFO -n workerB -Q for_task_B
複製代碼
相關文章
相關標籤/搜索