
注:本文使用的開發(fā)環(huán)境如下,如不同系統(tǒng)或環(huán)境之間可能存在差異,本文不做其它說明
操作系統(tǒng) : MacOS 10.13.4
Python版本 : Python 3.5.4
Django版本 : 2.0.5
celery 版本 : 4.1.0
celery后端 : Redis
特別強調(diào) 本文使用的是原生的 celery,因為celery官方已經(jīng)在3.x版本之后將 django-celery 兼容于 celery,不再使用 django-celery **
0x00 前言
最近要寫個Web項目,為了簡便就選擇使用Django作為后端開發(fā)了,突然發(fā)現(xiàn)程序要使用異步架構(gòu),在此原諒我廢話幾句說明為什么要使用異步架構(gòu),什么又是異步架構(gòu)(我相信你在看這篇文章的時候已經(jīng)對網(wǎng)絡(luò)請求和回應有所了解,也應當知道Django的請求回應流程,如果不了解,那就請直接在本篇文章下面點個贊之后關(guān)閉本網(wǎng)頁吧,因為接下來的內(nèi)容已經(jīng)對你目前的情況存在不適了,想看我的解釋,不存在的)
言歸正傳,因為Django的請求回應機制,必須在執(zhí)行完語句后才返回請求,但是在一些特殊的環(huán)境下,這樣的操作就會帶來很大的不便,比如程式在收到一個請求之后,要做很費時間的操作,用戶就會出現(xiàn)遲遲收不到網(wǎng)站的響應,比如我下面的例子。呃,先放個圖片鎮(zhèn)鎮(zhèn)場。

0x01 未做異步處理時的場景
部分代碼如下


其實sleep函數(shù)的存在感覺就是為我這樣的“流氓開發(fā)者”而存在的,不給錢就不給優(yōu)化,故意增加sleep的時間,滋滋(捂臉)。別打我
這里,我們發(fā)現(xiàn)當請求函數(shù)里面存在費時的函數(shù),請求就會出現(xiàn)延時,降低用戶體驗。接下來,我要開始表演啦?。。?前方高能
0x02 聽說 Django 與 celery 配合更美味
0x02-0 安裝 celery
讀到這里,我暫且認為您是會安裝Django并且會寫Django的基礎(chǔ)語句的,如果不是,建議您點個贊之后關(guān)閉本網(wǎng)站,下面的內(nèi)容可能會讓您感到糟糕。
首先,執(zhí)行安裝,安裝姿勢詳見 First Steps with Celery,如果不想打開請直接安裝下面的方式安裝,但如果您想更換 celery 的后端或者安裝時出現(xiàn)了錯誤,建議您優(yōu)先查看此網(wǎng)站進行解決。
Mac OS X 安裝
$ brew install Redis # Redis 安裝,需提前安裝 brew
$ pip install celery # pip 安裝celery庫
$ pip install redis # pip 安裝 redis庫
如果您沒有安裝 brew,建議您先安裝 brew 參考 brew安裝
Ubuntu 安裝
$ sudo apt install redis # Redis 安裝
$ pip install celery # pip 安裝celery庫
$ pip install redis # pip 安裝 redis庫
Linux 安裝
請訪問 redis 下載 最新的安裝包,本文使用的是在書寫本文這個時間時最新的安裝包,如官方發(fā)布更新,恕本文不另行通知更改。
$ wget http://download.redis.io/releases/redis-4.0.9.tar.gz
$ tar xzf redis-4.0.9.tar.gz
$ cd redis-4.0.9
$ make
# make完后 redis-4.0.9 目錄下會出現(xiàn)編譯后的redis服務(wù)程序redis-server,還有用于測試的客戶端程序redis-cli,兩個程序位于安裝目錄 src 目錄下:
# 下面啟動redis服務(wù).
$ cd src
$ ./redis-server
Windows 安裝 參考菜鳥教程-Redis 安裝
?? 作者未進行嘗試,所有錯誤請自行 Google
下載地址:https://github.com/MSOpenTech/redis/releases。
Redis 支持 32 位和 64 位。這個需要根據(jù)你系統(tǒng)平臺的實際情況選擇,這里我們下載 Redis-x64-xxx.zip壓縮包到 C 盤,解壓后,將文件夾重新命名為 redis。

打開一個 cmd 窗口 使用cd命令切換目錄到 C:\redis 運行 redis-server.exe redis.windows.conf 。
如果想方便的話,可以把 redis 的路徑加到系統(tǒng)的環(huán)境變量里,這樣就省得再輸路徑了,后面的那個 redis.windows.conf 可以省略,如果省略,會啟用默認的。輸入之后,會顯示如下界面:

0x02-1 編寫代碼
部分代碼截圖如下

代碼文件(./demo/demo/settings.py)
···
# Celery settings
CELERY_BROKER_URL = 'redis://localhost'
#: Only add pickle to this list if your broker is secured
#: from unwanted access (see userguide/security.html)
CELERY_ACCEPT_CONTENT = ['json']
CELERY_RESULT_BACKEND = 'redis://localhost'
CELERY_TASK_SERIALIZER = 'json'
代碼文件(./demo/demo/celery.py)
from __future__ import absolute_import, unicode_literals
import os
from celery import Celery
# set the default Django settings module for the 'celery' program.
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'demo.settings')
app = Celery('demo')
# this ‘demo’ is your project name !!!
# Using a string here means the worker doesn't have to serialize
# the configuration object to child processes.
# - namespace='CELERY' means all celery-related configuration keys
# should have a `CELERY_` prefix.
app.config_from_object('django.conf:settings', namespace='CELERY')
# Load task modules from all registered Django app configs.
app.autodiscover_tasks()
代碼文件(./demo/app/tasks.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
編輯完成代碼之后,開始運行web程式吧
首先,我們要啟動 redis 服務(wù),在終端執(zhí)行 redis-server 啟動服務(wù),如看見類似下面這樣的輸出,且沒有報錯,則redis啟動成功。
5433:C 14 May 11:24:01.463 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
5433:C 14 May 11:24:01.465 # Redis version=4.0.9, bits=64, commit=00000000, modified=0, pid=5433, just started
5433:C 14 May 11:24:01.465 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
5433:M 14 May 11:24:01.467 * Increased maximum number of open files to 10032 (it was originally set to 256).
_._
_.-``__ ''-._
_.-`` `. `_. ''-._ Redis 4.0.9 (00000000/0) 64 bit
.-`` .-```. ```\/ _.,_ ''-._
( ' , .-` | `, ) Running in standalone mode
|`-._`-...-` __...-.``-._|'` _.-'| Port: 6379
| `-._ `._ / _.-' | PID: 5433
`-._ `-._ `-./ _.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' | http://redis.io
`-._ `-._`-.__.-'_.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' |
`-._ `-._`-.__.-'_.-' _.-'
`-._ `-.__.-' _.-'
`-._ _.-'
`-.__.-'
5433:M 14 May 11:24:01.470 # Server initialized
5433:M 14 May 11:24:01.470 * DB loaded from disk: 0.000 seconds
5433:M 14 May 11:24:01.470 * Ready to accept connections
^C5433:signal-handler (1526271328) Received SIGINT scheduling shutdown...
5433:M 14 May 12:15:28.345 # User requested shutdown...
5433:M 14 May 12:15:28.345 * Saving the final RDB snapshot before exiting.
5433:M 14 May 12:15:28.348 * DB saved on disk
5433:M 14 May 12:15:28.348 # Redis is now ready to exit, bye bye...
之后新建終端,執(zhí)行命令 python manage.py runserver ,之后再新建一個終端,執(zhí)行命令 celery -A demo worker -l info (注: 此處的demo為Django項目名稱),沒有看到報錯的話,就證明運行成功了。
再次訪問網(wǎng)址

我們來看一下日志

在訪問網(wǎng)址5秒之后,自定義的add函數(shù)運行完成,并沒有阻塞我們的訪問響應。
0x03 結(jié)語
至此,我想你應該已經(jīng)初步了解如何在Django中使用celery了。
代碼相見 倉庫
感謝您的閱讀,點贊和打賞是一種美德,賣萌ヾ(≧O≦)〃嗷~