1. 程式人生 > >關於用celery做django內的非同步任務的注意事項

關於用celery做django內的非同步任務的注意事項

首先簡單介紹一下,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 函式執行完成,並沒有阻塞我們的訪問響應。