Django項目有一個耗時較長的update過程,希望在接到請求運行update過程的時候,Django應用仍能正常處理其他的請求,並且update過程要求不能並行,也不能漏掉任何一個請求
使用celery的solo模式解決
安裝redis
https://github.com/microsoftarchive/redis/releases
下載.msi文件安裝,會直接將redis注冊為windows服務
安裝celery與redis依賴
pip install celery
pip indatll redis
一個celery應用
# celery_test.py
import time
from celery import Celery
app = Celery('tasks', broker='redis://127.0.0.1:6379/0')
@app.task
def add(x, y):
time.sleep(5)
return x + y
啟動celery服務
celery -A celery_test.app worker --pool=solo -l info
查看完整的命令行參數列表
celery worker --help
對celery啟動命令的解釋
'-A' 是一個全局配置,定義了APP的位置
'--pool' 是POOL的配置,默認是prefork(並發),選擇solo之后,發送的任務不會被並發執行,在worker執行任務過程中,再次發送給worker的任務會排隊,執行完一個再執行另一個
'-l' 是WORKER的配置,定義了log級別
調用任務
>>> from celery_test import add
>>> add.delay(4,4)
因為啟動了solo模式,因此,可以看到在一個add沒有執行完前,即使再次發送執行add的任務,celery worker也會等到前一個任務執行完才去執行下一個
與Django結合
在裝載celery應用前先setup django
import time
import os
import django
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "demo.settings")
django.setup()
from celery import Celery
from django_app.update import update
app = Celery('tasks', broker='redis://127.0.0.1:6379/0', backend='redis://127.0.0.1:6379/0')
@app.task
def update_task():
update()
然后在views中調用task就可以了。
from celery_test import update_task
def update_api(request):
if request.method == "GET":
update_task.delay()
return HttpResponse(status=status.HTTP_200_OK)
執行過程中,程序的print信息會作為celery warning,報錯信息會作為celery error
日志
在啟動應用的時候指定日志文件路徑
-f log_path
不設置這個參數的時候,日志默認輸出到控制台