關於用celery做django內的非同步任務的注意事項
阿新 • • 發佈:2019-01-01
首先簡單介紹一下,Celery 是一個強大的分散式任務佇列,它可以讓任務的執行完全脫離主程式,甚至可以被分配到其他主機上執行。我們通常使用它來實現非同步任務(async task)和定時任務(crontab)。
如果你覺得自己的django專案有些行為邏輯實在沒必要耽誤在頁面跳轉上時,一方面可以用Ajax非同步提交來避免,而我更推薦用celery來做非同步處理。
注意:Celery 本身不提供佇列服務,官方推薦使用 RabbitMQ 和 Redis 等。
使用 Celery 實現非同步任務主要包含三個步驟:
- 建立一個 Celery 例項
- 啟動 Celery Worker
- 應用程式呼叫非同步任務
一、環境搭建
假設目前在Ubuntu系統環境下,我們採用redis作為訊息中介軟體,需要安裝以下依賴:
pip install django==1.9 安裝django
pip install celery==4.0 安裝celery(聽說最近的4.0版本直接支援django了)
sudo apt install redis
二、配置celery
首先,假設你的django目錄如下
project --manage.py --project --settings.py --wsgi.py --urls.py --__init__.py --__pycache__ --db.sqlite3
那麼,在settings.py中配置如下程式碼:
CELERY_BROKER_URL = 'redis://localhost'
CELERY_ACCEPT_CONTENT = ['json']
CELERY_RESULT_BACKEND = 'redis://localhost'
CELERY_TASK_SERIALIZER = 'json'
三、新增非同步模組
1、在settings.py的根目錄下,新建一個celery.py檔案,新增程式碼:
from __future__ import absolute_import, unicode_literals import os from celery import Celery os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'project.settings') #實際上這裡填入的是你專案的settings路徑 app = Celery('project') # 這裡的‘project’是你的專案名稱 app.config_from_object('django.conf:settings', namespace='CELERY') #namespace='CELERY'表示,所有與celery相關的配置都以'CELERY'為字首 # 從所有已註冊的Django app配置中載入任務模組 app.autodiscover_tasks()
2、隨後在你的APP目錄下,新建一個task.py檔案:
import time
from celery import Celery
celery_app = Celery('tasks', backend='redis://localhost', broker='redis://localhost')
# this is celery settings
# this is a function about need many time
@celery_app.task
def add(a, b):
time.sleep(5)
return a + b
這樣就完成一個簡單的非同步處理了
四、執行測試
首先在開啟一個終端,開啟redis,在終端輸入redis-server
,見到如下圖示就是成功了:
_.-``__ ''-._
_.-`` `. `_. ''-._ Redis 4.0.9 (00000000/0) 64 bit
.-`` .-```. ```\/ _.,_ ''-._
( ' , .-` | `, ) Running in standalone mode
|`-._`-...-` __...-.``-._|'` _.-'| Port: 6379
| `-._ `._ / _.-' | PID: 5433
`-._ `-._ `-./ _.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' | http://redis.io
`-._ `-._`-.__.-'_.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' |
`-._ `-._`-.__.-'_.-' _.-'
`-._ `-.__.-' _.-'
`-._ _.-'
`-.__.-'
之後新建終端,執行命令 python manage.py runserver
,之後再新建一個終端,執行命令 celery -A project worker -l info
(注: 此處的project為Django專案名稱),沒有看到報錯的話,就證明執行成功了。
終端日誌中可以發現,在訪問網址5秒之後,自定義的 add 函式執行完成,並沒有阻塞我們的訪問響應。