序言
在上一篇博客中記錄了Celery的安裝及初步簡單使用,如果需要請前往查看,本文在上一篇的環(huán)境基礎(chǔ)上繼續(xù)記錄Celery的配置使用及配置分離。前一篇博客的例子是將Celery的實(shí)例配置和任務(wù)都寫在了tasks.py的python文件中,這在多模塊任務(wù)或者大型項(xiàng)目(需要自定義很多的Celery配置)中就不太方便,我們把配置和任務(wù)及測試都分離出來,這樣我們要修改其中某一個(gè)配置就可以直接去配置文件中找。接下來我們將Celery的配置獨(dú)立于一個(gè)文件,任務(wù)也獨(dú)立于一個(gè)文件。
再啰嗦一下安裝的環(huán)境版本:
- system:Ubuntu 16.04
- python:Python 3.5.2
- celery:4.2.0
- redis:2.10.6
文件目錄
新建一個(gè)command文件夾(我的目錄為/home/youjun/celery/command ),其中的目錄結(jié)構(gòu)如下:
celery/
|-- command/
|-- |-- __init__.py
|-- |-- application.py
|-- |-- config.py
|-- |-- tasks.py
|-- |-- test.py
注意:官網(wǎng)中說明了在你先寫好的celery程序包下必須包含一個(gè)celery.py的文件,由于我們運(yùn)行(ctr+alt+t打開終端,進(jìn)入celery程序包所在目錄,例如我的是:cd /home/youjun/celery ,然后執(zhí)行啟動命令celery -A command worker --loglevel=info ,command即為我們寫好的celery程序包)的時(shí)候,celery會去尋找command下的celery.py模塊開始運(yùn)行,如果沒有這個(gè)模塊,那么就會報(bào)錯(cuò)了。我們這里沒有celery.py文件,那么也有對應(yīng)的解決辦法(后面說明)。
模塊
__init__模塊
在__init__.py文件中寫入如下內(nèi)容:
# -*- coding: utf-8 -*-
# ----------------------------------------------
# @Time : 18-8-23 上午10:00
# @Author : YYJ
# @File : __init__.py.py
# @CopyRight: ZDWL
# ----------------------------------------------
import command.application as celery
__all__ = ('celery', 'config', 'tasks')
前面說了在command下必須有一個(gè)celery.py模塊,我們這里沒有,用的是application.py文件,然后我們可以通過第一行代碼把a(bǔ)pplication取一個(gè)別名叫celery,這樣celery程序就能找到command下的celery模塊了(實(shí)際是application,當(dāng)然你可以修改名字為任意的了),如果不理解建議去看看Python的__init__.py文件和__all__的作用。
application模塊
- 內(nèi)容
在application.py文件中寫入如下內(nèi)容:
# -*- coding: utf-8 -*-
# ----------------------------------------------
# @Time : 18-8-23 上午10:05
# @Author : YYJ
# @File : app.py
# @CopyRight: ZDWL
# ----------------------------------------------
from __future__ import absolute_import
from celery import Celery
# 創(chuàng)建Celery實(shí)例,我們稱之為Celery應(yīng)用程序或簡稱app。這個(gè)實(shí)例是Celery中執(zhí)行的所有操作的入口點(diǎn),例如創(chuàng)建任務(wù)和管理工作程序
# 因此其他模塊必須可以導(dǎo)入它。
app = Celery()
# 配置配置文件
app.config_from_object('command.config')
這一塊就兩點(diǎn),一就是創(chuàng)建一個(gè)celery實(shí)例,二就是配置celery實(shí)例的配置文件,我們創(chuàng)建celery實(shí)例的時(shí)候不傳任何參數(shù),我們只需要把所有的配置放在command下的config.py模塊中,然后通過app.config_from_object('command.config') 告訴celery配置文件去使用command下的config.py模塊。
config模塊
- 內(nèi)容
在config.py文件中寫入如下內(nèi)容:
# -*- coding: utf-8 -*-
# ----------------------------------------------
# @Time : 18-8-23 上午10:01
# @Author : YYJ
# @File : config.py
# @CopyRight: ZDWL
# ----------------------------------------------
# 配置代理
broker_url = 'redis://127.0.0.1:6379/0'
# 配置結(jié)果后端
result_backend = 'redis://127.0.0.1:6379/0'
enable_utc = False
# 配置時(shí)區(qū)
timezone = 'Asia/Shanghai'
# 配置需要導(dǎo)入的任務(wù)模塊
imports = ('command.tasks', )
在這里你可以配置你的配置參數(shù),其中重要的是代理和任務(wù)的導(dǎo)入,我們使用redis(broker_url和result_backend參數(shù))做結(jié)果后端,imports里是我們需要導(dǎo)入的模塊,我們需要把我們的任務(wù)導(dǎo)入,所以必須在這里對任務(wù)tasks模塊寫入imports配置,注意這里全部都是小寫參數(shù)名,當(dāng)然我們可以給參數(shù)加前綴(在下一篇博客中介紹)。
tasks模塊
- 內(nèi)容
在tasks.py文件中寫入如下內(nèi)容:
# -*- coding: utf-8 -*-
# ----------------------------------------------
# @Time : 18-8-23 上午10:02
# @Author : YYJ
# @File : tasks.py
# @CopyRight: ZDWL
# ----------------------------------------------
from __future__ import absolute_import
from command.application import app
# 這里定義了一個(gè)加法的任務(wù),并使用@app.task來注冊任務(wù)
@app.task
def add(x, y):
z = x + y
print(z)
return z
這一塊就是你要執(zhí)行的任務(wù)代碼了,這里簡單定義了一個(gè)加法的任務(wù)(在具體的項(xiàng)目中,你可以改成你自己的任務(wù),比如你可以在這里寫一個(gè)統(tǒng)計(jì)數(shù)據(jù)庫中訂單今日的銷售總額的任務(wù)函數(shù)),內(nèi)容不多,先從command.application導(dǎo)入我們創(chuàng)建的celery實(shí)例app,然后通過裝飾器@app.task將add函數(shù)注冊為一個(gè)celery任務(wù)。
現(xiàn)在是只有一個(gè)task模塊,當(dāng)我們?nèi)蝿?wù)比較多的時(shí)候也可以分離多個(gè)task模塊,實(shí)質(zhì)就是在config中的imports中添加你要導(dǎo)入的任務(wù),注意你的任務(wù)在系統(tǒng)環(huán)境中能找到,不然會報(bào)No module … 的異常,具體的多任務(wù)模塊在后面的博客再詳細(xì)點(diǎn)介紹。
test模塊
- 內(nèi)容
在test.py文件中寫入如下內(nèi)容:
# -*- coding: utf-8 -*-
# ----------------------------------------------
# @Time : 18-10-19 下午2:50
# @Author : YYJ
# @File : test.py
# @CopyRight: ZDWL
# ----------------------------------------------
import sys
# 將路徑加入系統(tǒng)環(huán)境中
sys.path.append('/home/youjun/celery')
# 動態(tài)導(dǎo)入
tasks = __import__('command.tasks', fromlist=['add', ])
tasks.add.delay(4, 5)
這里有比較重要的東西,注意我的test.py是可以放在任意的地方運(yùn)行的,原因在于我使用sys.path.append('/home/youjun/celery') 將我寫的celery程序包c(diǎn)ommand所在的路徑加到了系統(tǒng)環(huán)境中,這樣我們相當(dāng)于把我們的command包臨時(shí)安裝到系統(tǒng)里(這里我說明一下,我們平時(shí)pip3安裝的一些包都在/usr/local/lib/python3.5/dist-packages 下,比如我們安裝了celery對吧,那么在這個(gè)目錄下就能找到celery目錄,那么我們在導(dǎo)入的時(shí)候做了如此一個(gè)導(dǎo)入:from celery.apps.beat import Beat 那么是怎么導(dǎo)入的呢,Python會從系統(tǒng)環(huán)境中所有的路徑中去找哪個(gè)目錄下有celery/apps/beat.py(beat.py里還有Beat對象) 目錄的,于是找到了完整目錄是/usr/local/lib/python3.5/dist-packages/celery/apps/beat.py 如果找遍所有的環(huán)境都沒有找到,那么就會報(bào)一個(gè)錯(cuò)誤了,我們這里使用sys.path.append('/home/youjun/celery') 就是在這個(gè)程序運(yùn)行期間把這個(gè)路徑也加入環(huán)境中也就是Python在這之后運(yùn)行的時(shí)候也會在這個(gè)路徑下去找你的包或者模塊,那么我們就可以使用Python動態(tài)導(dǎo)入我們的任務(wù)模塊了,這里必須把這個(gè)路徑加入環(huán)境中,因?yàn)槲覀儎討B(tài)導(dǎo)入的模塊中有from command.application import app ,不導(dǎo)入的話是找不到command包的)。
剩下的就是動態(tài)導(dǎo)入__import__的使用了,這里不做解釋,不是本篇博客內(nèi)容。最后一行代碼是調(diào)用任務(wù)。這個(gè)測試文件可以放在任何地方執(zhí)行,前提是把你編寫的celery程序包的路徑如上加入環(huán)境中,我的為/home/youjun/celery ,需要改為你自己的目錄,所以你的項(xiàng)目假設(shè)需要自己調(diào)用的話就可以派上用場。
運(yùn)行測試
進(jìn)入你的celery程序包(我的為command)所在目錄(我的為),執(zhí)行celery -A command worker --loglevel=info (command就是要運(yùn)行的celery包名,改為你自己的),執(zhí)行結(jié)果如下:

進(jìn)入你的test.py所在目錄(我的為/home/youjun/celery/command/ ),執(zhí)行python3 test.py ,結(jié)果如下:

最后執(zhí)行了調(diào)用后的結(jié)果如下,可以看到打印的結(jié)果為9:

結(jié)語
到此celery的初配置及任務(wù)獨(dú)立,初步配置就結(jié)束了,講解的不少有些可能還不詳細(xì),如有問題歡迎交流指正,原創(chuàng)文章不易,如有幫助到你請點(diǎn)個(gè)贊。在下一篇將會介紹celery配置和使用contab定時(shí)任務(wù),以及結(jié)合django的ORM操作數(shù)據(jù)庫。
上一篇:Django定時(shí)器Celery+Redis(一)Celery安裝使用
下一篇:Django定時(shí)器Celery+Redis(三)Celery配置詳解及結(jié)合Django定時(shí)操作數(shù)據(jù)庫(努力編寫中。。。)
|