Celery 和 Redis 入門

Celery 是一個廣泛應(yīng)用于網(wǎng)絡(luò)應(yīng)用程序的任務(wù)處理系統(tǒng)功舀。

它可以在以下情況下使用:

在請求響應(yīng)周期中做網(wǎng)絡(luò)調(diào)用鲁纠。服務(wù)器應(yīng)當立即響應(yīng)任何網(wǎng)絡(luò)請求批狐。如果在請求響應(yīng)周期內(nèi)需要進行網(wǎng)絡(luò)調(diào)用觅丰,則應(yīng)在周期外完成調(diào)用盖腕。例如當用戶在網(wǎng)站上注冊時勺鸦,需要發(fā)送激活郵件并巍。發(fā)送郵件是一種網(wǎng)絡(luò)調(diào)用,耗時2到3秒换途。用戶應(yīng)該無需等待這2到3秒懊渡。因此,發(fā)送激活郵件應(yīng)當在請求響應(yīng)周期外完成军拟,celery 就能實現(xiàn)這一點剃执。

將一個由幾個獨立部分組成的大任務(wù)分成多個小任務(wù)。假設(shè)你想知道臉書用戶的時間流懈息。臉書提供不同的端點來獲取不同的數(shù)據(jù)肾档。譬如,一個端點用以獲取用戶時間流中的圖片辫继,一個端點獲取用戶時間流中的博文怒见,一個端點得到用戶的點贊信息等。如果你的函數(shù)需要和臉書的5個端點依此通信姑宽,每個網(wǎng)絡(luò)調(diào)用平均耗時2秒遣耍,你將需要10秒完成一次函數(shù)執(zhí)行。但是低千,你可以把這項工作分為5個獨立的任務(wù)(你很快就會發(fā)現(xiàn)這很容易做到)配阵,并讓 celery 來處理這些任務(wù)馏颂。Celery 可以并行地與這5個端點通信,在2秒之內(nèi)就能得到所有端點的響應(yīng)棋傍。

簡單的 celery 例子

假設(shè)我們有一個函數(shù)救拉,并傳給它一個網(wǎng)址列表。該函數(shù)需要獲取這些網(wǎng)址的響應(yīng)瘫拣。

沒有使用 celery

創(chuàng)建文件celery_blog.py

import requests
import time

def func(urls):
    start = time.time()
    for url in urls:
        resp = requests.get(url)
        print resp.status_code
    print "It took", time.time() - start, "seconds"

if __name__ == "__main__":
    func(["http://oneapm.com", "http://jd.com", "https://taobao.com", "http://baidu.com", "http://news.oneapm.com"])

運行:

python celery_blog.py

輸出:


Celery 和 Redis 入門
Celery 和 Redis 入門
使用 celery

調(diào)用 celery 的程序中最重要的組成部分為 celery worker亿絮。

在 web 應(yīng)用程序注冊的例子中,celery worker 用于發(fā)送郵件麸拄。

在臉書的例子中派昧, celery worker 用于獲取不同的網(wǎng)址。

在我們的 celery_blog.py 例子中拢切, celery worker 用于獲取 URL蒂萎。
celery worker 和你的應(yīng)用程序/腳本是不同的進程,彼此獨立運行淮椰。所以你的應(yīng)用程序/腳本和 celery 需要一些方法來相互溝通五慈。

應(yīng)用程序代碼需要把任務(wù)放在 celery worker 可以取出并執(zhí)行的位置。譬如主穗,應(yīng)用程序代碼將任務(wù)放在消息隊列中泻拦,celery worker 從消息隊列領(lǐng)取任務(wù)并執(zhí)行任務(wù)。我們將使用 Redis 作為消息隊列忽媒。

請確認你已安裝 Redis争拐,并可以運行redis-server

請確認你已安裝 celery晦雨。

修改文件 celery_blog.py架曹,如下:

from celery import Celery
 
app = Celery('celery_blog',bloker='redis://localhost:6379/1')

@app.task
def fetch_url(url):
     resp = requests.get(url)
     print resp.status_code
 
def func(urls):
     for url in urls:
       fetch_url.delay(url)
    
if __name__ == "__main__":
     func(["http://oneapm.com", "http://jd.com", "https://taobao.com", "http://baidu.com", "http://news.oneapm.com"])

代碼解釋:我們需要一個 celery 實例來啟動程序,因此創(chuàng)建了一個名為 app 的 celery 實例金赦。

在3個終端中啟動:

第一個終端音瓷,運行 redis-server

第二個終端,運行 celery worker -A celery_blog -l info -c 5 夹抗,通過輸出可以看到 celery 成功運行。

第三個終端纵竖,運行腳本 python celery_blog.py

可以看到第二個終端輸出如下:

Celery 和 Redis 入門
Celery 和 Redis 入門
將 celery 代碼和配置保存在不同文件中

上面的例子中漠烧,我們只寫了一個 celery 任務(wù)。但您的項目可能涉及多個模塊靡砌,您可能希望在不同的模塊中有不同的任務(wù)已脓。所以讓我們將 celery 配置移到單獨的文件中。

創(chuàng)建 celery_config.py

from celery import Celery

app = Celery('celery_config', broker='redis://localhost:6379/0', include=['celery_blog'])

修改 celery_blog.py 代碼如下:

import  requests
from celery_config import app

@app.task
def fetch_url(url):
     resp = requests.get(url)
     print resp.status_code

def func(urls):
    for url in urls:
       fetch_url.delay(url)
    
if __name__ == "__main__":
    func(["http://oneapm.com", "http://jd.com", "https://taobao.com", "http://baidu.com", "http://news.oneapm.com"])

停掉之前的 celery worker 通殃,運行:

celery worker -A celery_config -l info -c 5

打開 ipython 度液,運行如下命令:

In [1]: from celery_blog import func
In [2]: func(["http://oneapm.com", "http://jd.com", "https://taobao.com", "http://baidu.com", "http://news.oneapm.com"])

輸出如下:

Celery 和 Redis 入門
Celery 和 Redis 入門
在不同文件中添加新的任務(wù)

您可以添加新的模塊厕宗,并在該模塊中定義一個任務(wù)。用以下內(nèi)容創(chuàng)建一個模塊 celery_add.py

from celery_config import app

@app.task
def add(a, b):
    return a + b

改變 celery_config.py 包含新的模塊 celery_add.py堕担,如下:

from celery import Celery

app = Celery('celery_config', broker='redis://localhost:6379/0', include=['celery_blog', 'celery_add'])

在 ipython 輸入:

In [1]: from celery_add import add
In [2]: add.delay(4, 5)

輸出如下:

Celery 和 Redis 入門
Celery 和 Redis 入門
在不同的機器上分開使用 Redis 和 celery

到目前為止已慢,我們的腳本、celery worker 和 Redis 都運行在同一機器中霹购。其實并無這種必要佑惠,這三者可以運行在不同機器上。

celery 任務(wù)涉及到網(wǎng)絡(luò)請求齐疙,因此膜楷,在網(wǎng)絡(luò)優(yōu)化的機器上使用 celery worker 能提高任務(wù)運行速度。Redis 是一種內(nèi)存數(shù)據(jù)庫贞奋,在內(nèi)存優(yōu)化的機器上運行效率更高赌厅。

在這個例子中,我將在本地系統(tǒng)運行腳本和 celery worker轿塔,在分開的服務(wù)器上運行 Redis察蹲。

修改 celery_config.py 為:

app = Celery('celery_config', broker='redis://192.168.118.148:6379/0', include=['celery_blog'])
Celery 和 Redis 入門
Celery 和 Redis 入門

現(xiàn)在我運行任何任務(wù),腳本都將把他放在 Redis 運行的服務(wù)器(192.168.118.148)上面催训。

celery worker 也與 192.168.118.148 溝通,在這個 Redis 服務(wù)器上得到任務(wù)并執(zhí)行它洽议。

注意:您必須使用正在運行 redis-server 的服務(wù)器地址。我的服務(wù)器已停止Redis,所以你將無法連接到 Redis漫拭。

參考文章:Getting started with Celery and Redis

本文系 OneAPM 工程師整理亚兄。OneAPM 是應(yīng)用性能管理領(lǐng)域的新興領(lǐng)軍企業(yè),能幫助企業(yè)用戶和開發(fā)者輕松實現(xiàn):緩慢的程序代碼和 SQL 語句的實時抓取采驻。想閱讀更多技術(shù)文章审胚,請訪問 OneAPM 官方博客

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末礼旅,一起剝皮案震驚了整個濱河市膳叨,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌痘系,老刑警劉巖菲嘴,帶你破解...
    沈念sama閱讀 222,183評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異汰翠,居然都是意外死亡龄坪,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評論 3 399
  • 文/潘曉璐 我一進店門复唤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來健田,“玉大人,你說我怎么就攤上這事佛纫〖司郑” “怎么了总放?”我有些...
    開封第一講書人閱讀 168,766評論 0 361
  • 文/不壞的土叔 我叫張陵,是天一觀的道長好爬。 經(jīng)常有香客問我局雄,道長,這世上最難降的妖魔是什么抵拘? 我笑而不...
    開封第一講書人閱讀 59,854評論 1 299
  • 正文 為了忘掉前任哎榴,我火速辦了婚禮,結(jié)果婚禮上僵蛛,老公的妹妹穿的比我還像新娘尚蝌。我一直安慰自己,他們只是感情好充尉,可當我...
    茶點故事閱讀 68,871評論 6 398
  • 文/花漫 我一把揭開白布飘言。 她就那樣靜靜地躺著,像睡著了一般驼侠。 火紅的嫁衣襯著肌膚如雪姿鸿。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,457評論 1 311
  • 那天倒源,我揣著相機與錄音苛预,去河邊找鬼。 笑死笋熬,一個胖子當著我的面吹牛热某,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播胳螟,決...
    沈念sama閱讀 40,999評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼昔馋,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了糖耸?” 一聲冷哼從身側(cè)響起秘遏,我...
    開封第一講書人閱讀 39,914評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎嘉竟,沒想到半個月后邦危,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,465評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡周拐,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,543評論 3 342
  • 正文 我和宋清朗相戀三年铡俐,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片妥粟。...
    茶點故事閱讀 40,675評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖吏够,靈堂內(nèi)的尸體忽然破棺而出勾给,到底是詐尸還是另有隱情滩报,我是刑警寧澤,帶...
    沈念sama閱讀 36,354評論 5 351
  • 正文 年R本政府宣布播急,位于F島的核電站脓钾,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏桩警。R本人自食惡果不足惜可训,卻給世界環(huán)境...
    茶點故事閱讀 42,029評論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望捶枢。 院中可真熱鬧握截,春花似錦、人聲如沸烂叔。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蒜鸡。三九已至胯努,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間逢防,已是汗流浹背叶沛。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留忘朝,地道東北人灰署。 一個月前我還...
    沈念sama閱讀 49,091評論 3 378
  • 正文 我出身青樓,卻偏偏與公主長得像辜伟,于是被迫代替她去往敵國和親氓侧。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,685評論 2 360

推薦閱讀更多精彩內(nèi)容