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提供了兩個序列化的格式,pickle
和json
,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
複製代碼
若是任務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
複製代碼