python huey中文文檔(二)

緊接著上回繼續(xù)翻譯吧狈定。有關huey這個python寫的的輕量級消息隊列

個人才疏學淺粗梭,可能很多英文都要借助翻譯軟件巷挥,但盡量做到能夠易于理解烹卒。


教程指導

這個文檔的目的是為了幫助人盡可能快速使用huey章咧。

簡單入門

使用huey需要注意有如下三個主要的組成(或者過程):

  • 生產(chǎn)者倦西,例如web應用等。
  • 消費者赁严,運行放置在消息隊列中的任務(jobs)扰柠。
  • 隊列,存放任務疼约。例如Redis等卤档。

底下的截圖展示了上述三個不同的過程。左邊是生產(chǎn)者:一個簡單的程序詢問用戶要輸入多少的“豆子”程剥。右上角消費者一直運行劝枣,它正在做“計算”,舉例如圖中所示打印了有多少“豆子”被計數(shù)织鲸。右下角是是一個隊列舔腾,圖中使用的是Redis。我們可以看到任務被添加(LPUSH)入隊列和從數(shù)據(jù)庫中讀取(BRPOP)任務搂擦。

截圖

自我嘗試

假定你安裝了huey稳诚,讓我們來看一下代碼例子。
第一步先配置隊列瀑踢。消費者需要指定一個Huey實例扳还,這代表了使用的后端類型。

# config.py
from huey import RedisHuey

huey = RedisHuey()

huey對象封裝了隊列橱夭。隊列負責存儲和取回消息氨距,你的應用程序代碼使用huey實例來聯(lián)系函數(shù)調(diào)用。我們來看一下怎么使用huey來連接一個計算豆子的函數(shù):

# tasks.py
from config import huey # import the huey we instantiated in config.py


@huey.task()
def count_beans(num):
    print('-- counted %s beans --' % num)

上述代碼展現(xiàn)了如何用API定義最終被消費者執(zhí)行的“任務”——用task()裝飾器簡單裝飾你想要讓消費者運行的函數(shù)任務棘劣。而當它被調(diào)用時候俏让,主進程將立即返回而不是進入函數(shù)內(nèi)部。在消費者進程中會看到這個新消息并運行這個函數(shù)。
我們的主程序很簡單舆驶。它導入了配置和任務——這確保了在我們根據(jù)指定的配置運行消費者時橱健,所有任務都會被加載入內(nèi)存而钞。

# main.py
from config import huey  # import our "huey" object
from tasks import count_beans  # import our task


if __name__ == '__main__':
    beans = raw_input('How many beans? ')
    count_beans(int(beans))
    print('Enqueued job to count %s beans' % beans)

啟動腳本需要依次進行以下步驟:

  1. 確保本地運行Redis
  2. 確保安裝了huey
  3. 啟動消費者: huey_consumer.py main.huey(注意是"main.huey"而不是"config.huey"沙廉,這里提示一下huey_consumer.py需要自己從huey腳本的bin下拷貝到當前的路徑,這樣才能用該命令來啟動臼节。)
  4. 運行主程序: python main.py

獲取結果

上面的例子實現(xiàn)了一個“發(fā)送并且忘記”的方法撬陵,但是如果你的應用程序需要對任務的結果做些什么呢?要從你的任務中獲取結果网缝,只需返回任務函數(shù)中的值即可巨税。

如果你得到了存儲結果但不使用它們,那么可能會浪費大量空間粉臊,特別是如果你的任務量很高草添。要禁用存儲功能,可以在初始化Huey實例時返回None或指定result_store = False扼仲。

為了更好地說明獲取結果的代碼远寸,我們還將修改tasks.py模塊以返回一個字符串,而不是打印結果到標準輸出窗口:

from config import huey


@huey.task()
def count_beans(num):
    print('-- counted %s beans --' % num)
    return 'Counted %s beans' % num

我們準備向消費者輸入大量任務屠凶。不是簡單地執(zhí)行主程序驰后,我們這回將啟動一個解釋器并運行以下操作:

>>> from main import count_beans
>>> res = count_beans(100)
>>> print(res)                      # What is "res" ?
<huey.api.TaskResultWrapper object at 0xb7471a4c>

>>> res()                          # Get the result of this task
'Counted 100 beans'

按照與上一個例子相同的布局,下面是三個主要工作流程的截圖:

  1. 左邊矗愧,解釋器生成任務并詢問結果
  2. 右上角灶芝, 消費者執(zhí)行任務并存儲結果
  3. 右下角是Redis數(shù)據(jù)庫,我們能夠看到它儲存結果然后在我們?nèi)』財?shù)據(jù)后刪除它們
結果

延遲執(zhí)行任務

將某個特定任務排入任意時間來執(zhí)行通常很用的唉韭,例如夜涕,標記在某個時間發(fā)布的博客條目。
這在huey中很容易完成属愤。返回上一節(jié)描述的在解釋器中執(zhí)行的代碼钠乏,讓我們安排一個一分鐘后執(zhí)行的數(shù)豆子的任務,然后看看huey怎么處理它春塌。執(zhí)行以下代碼:

>>> import datetime
>>> res = count_beans.schedule(args=(100,), delay=60)
>>> print(res)
<huey.api.TaskResultWrapper object at 0xb72915ec>

>>> res()  # This returns None, no data is ready.

>>> res()  # A couple seconds later.

>>> res(blocking=True)  # OK, let's just block until its ready
'Counted 100 beans'

你也可以使用datetime類型來指定“預計到達時間”:

>>> in_a_minute = datetime.datetime.now() + datetime.timedelta(seconds=60)
>>> res = count_beans.schedule(args=(100,), eta=in_a_minute)

默認情況下晓避,Huey實例以UTC時間運行。這對計劃任務的影響是只壳,當使用本地的時間時俏拱,它們必須與datetime.utcnow()相關聯(lián)。

在上述代碼中我們不采用utcnow()的原因是schedule()包含默認值為True的第三個參數(shù)叫做convert_utc吼句。所以在上面的代碼中锅必,datetime在被發(fā)送到隊列之前從本地時間轉換為了UTC

當你想要以本地時間模式運行(-o),你需要總是指定schedule()的第三個參數(shù)convert_utc=False搞隐,包括在指定delay參數(shù)時驹愚。

redis的輸出,我們看到以下(簡化內(nèi)容):

+1325563365.910640 "LPUSH" count_beans(100)
+1325563365.911912 "BRPOP" wait for next job
+1325563365.912435 "HSET" store 'Counted 100 beans'
+1325563366.393236 "HGET" retrieve result from task
+1325563366.393464 "HDEL" delete result after reading

截圖也展示了相同的內(nèi)容:

安排

重試失敗任務

Huey支持有限次重試失敗任務劣纲。如果在執(zhí)行任務期間引發(fā)了異常逢捺,但是你已經(jīng)指定了retries參數(shù),則任務將重新入隊并再次嘗試癞季,直到指定的重試次數(shù)劫瞳。
如下顯示的一個任務,將重試3次绷柒,每次都會拋出異常:

# tasks.py
from config import huey


@huey.task()
def count_beans(num):
    print('-- counted %s beans --' % num)
    return 'Counted %s beans' % num

@huey.task(retries=3)
def try_thrice():
    print('trying....')
    raise Exception('nope')

控制臺輸出顯示我們的任務在解釋器會話中被調(diào)用志于,然后當消費者接收然后執(zhí)行它時,我們看到它失敗但進行了重試:

重試

在重試之間等待一定的時間間隔通常是個好的主意废睦。你可以指定重試之間的delay參數(shù)(以秒為單位)伺绽,這會是任務重試之前等待的最短時間。這里我們修改代碼使它包含delay參數(shù)嗜湃,并打印當前時間來顯示它的工作奈应。

# tasks.py
from datetime import datetime

from config import huey

@huey.task(retries=3, retry_delay=10)
def try_thrice():
    print('trying....%s' % datetime.now())
    raise Exception('nope')

下面的控制臺輸出顯示正在重試的任務,同時在重試過程中净蚤,我還在添加了“數(shù)豆子”的任務——處于正常執(zhí)行狀態(tài)钥组。

添加延遲

定期任務

huey支持的另一個使用模式是定期執(zhí)行任務。依照crontab行為今瀑,同時遵循類似的語法程梦。定期執(zhí)行的任務,不應返回有意義的結果橘荠,也不應接受任何參數(shù)屿附。
讓我們添加一個每分鐘打印一次字符竄的新任務——我們將使用它來測試消費者是否正在按計劃執(zhí)行任務。

# tasks.py
from datetime import datetime
from huey import crontab

from config import huey

@huey.periodic_task(crontab(minute='*'))
def print_time():
    print(datetime.now())

現(xiàn)在哥童,當我們運行消費者時挺份,它將每分鐘開始打印時間:

定時任務

取消或暫停任務

huey可以停止任務執(zhí)行。這適用于正常任務贮懈,延遲任務和定期任務匀泊。
為了“revoke(撤銷)”任務,你需要在實例化Huey對象時指定一個result_store參數(shù)朵你。
如果消費者沒有開始執(zhí)行任務各聘,你可以取消正常的任務:

# count some beans
res = count_beans(10000000)

# provided the command has not started executing yet, you can
# cancel it by calling revoke() on the TaskResultWrapper object
res.revoke()

這同樣適用于延遲任務:

res = count_beans.schedule(args=(100000,), eta=in_the_future)
res.revoke()

# and you can actually change your mind and restore it, provided
# it has not already been "skipped" by the consumer
res.restore()

要撤消給定任務的所有實例,請對任務本身使用revoke()restore()方法:

count_beans.revoke()
assert count_beans.is_revoked() is True

res = count_beans(100)
assert res.is_revoked() is True

count_beans.restore()
assert count_beans.is_revoked() is False

取消或暫停定期任務

當我們開始處理定期任務時抡医,撤銷選項會更有意思躲因。
我們將使用打印時間代碼作為示例:

@huey.periodic_task(crontab(minute='*'))
def print_time():
    print(datetime.now())

我們可以防止周期性的任務在下一個循環(huán)中執(zhí)行:

# only prevent it from running once
print_time.revoke(revoke_once=True)

由于上述任務每分鐘執(zhí)行一次,我們將看到輸出將跳過下一次的一分鐘,然后才恢復正常大脉。
我們也可以防止任務執(zhí)行直到指定時間:

# prevent printing time for 10 minutes
now = datetime.datetime.utcnow()
in_10 = now + datetime.timedelta(seconds=600)

print_time.revoke(revoke_until=in_10)

當指定revoke_until設置搞监,如果消費者以UTC默認時間模式運行,本地時間需要關聯(lián)到datetime.utcnow()镰矿。如果消費者以本地時間(-o參數(shù)指定)琐驴,則可以使用datetime.now()

最后衡怀,我們可以防止任務無限期地運行:

# will not print time until we call revoke() again with
# different parameters or restore the task
print_time.revoke()
assert print_time.is_revoked() is True

我們隨時可以恢復任務棍矛,它將會正常執(zhí)行:

print_time.restore()

查看更多

這總結了huey的基本使用模式安疗。以下是有關API其他方面的詳細信息的鏈接:

  • Huey——負責協(xié)調(diào)可執(zhí)行任務和隊列后端
  • Huey.task()——裝飾器來指示可執(zhí)行任務
  • Huey.periodic_task() ——裝飾器以指示以周期性間隔執(zhí)行的任務
  • TaskResultWrapper.get() ——從任務獲取返回值
  • crontab() ——用于定義執(zhí)行周期性任務的間隔時間

結束

有一周混過去了抛杨,繼續(xù)啃爬蟲去了。荐类。怖现。。

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末玉罐,一起剝皮案震驚了整個濱河市屈嗤,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌吊输,老刑警劉巖饶号,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異季蚂,居然都是意外死亡茫船,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進店門扭屁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來算谈,“玉大人,你說我怎么就攤上這事料滥∪谎郏” “怎么了?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵葵腹,是天一觀的道長高每。 經(jīng)常有香客問我,道長践宴,這世上最難降的妖魔是什么鲸匿? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮浴井,結果婚禮上晒骇,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好洪囤,可當我...
    茶點故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布徒坡。 她就那樣靜靜地躺著,像睡著了一般瘤缩。 火紅的嫁衣襯著肌膚如雪喇完。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天剥啤,我揣著相機與錄音锦溪,去河邊找鬼。 笑死府怯,一個胖子當著我的面吹牛刻诊,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播牺丙,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼则涯,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了冲簿?” 一聲冷哼從身側響起粟判,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎峦剔,沒想到半個月后档礁,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡吝沫,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年呻澜,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片野舶。...
    茶點故事閱讀 38,018評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡易迹,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出平道,到底是詐尸還是另有隱情睹欲,我是刑警寧澤,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布一屋,位于F島的核電站窘疮,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏冀墨。R本人自食惡果不足惜闸衫,卻給世界環(huán)境...
    茶點故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望诽嘉。 院中可真熱鬧蔚出,春花似錦弟翘、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至趋翻,卻和暖如春睛琳,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背踏烙。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工师骗, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人讨惩。 一個月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓辟癌,卻偏偏與公主長得像,于是被迫代替她去往敵國和親步脓。 傳聞我的和親對象是個殘疾皇子愿待,可洞房花燭夜當晚...
    茶點故事閱讀 42,762評論 2 345

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

  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理浩螺,服務發(fā)現(xiàn)靴患,斷路器,智...
    卡卡羅2017閱讀 134,599評論 18 139
  • 本文章是 Vert.x 藍圖系列 的第二篇教程要出。全系列: Vert.x Blueprint 系列教程(一) | 待...
    sczyh30閱讀 2,016評論 0 10
  • 來源 RabbitMQ是用Erlang實現(xiàn)的一個高并發(fā)高可靠AMQP消息隊列服務器鸳君。支持消息的持久化、事務患蹂、擁塞控...
    jiangmo閱讀 10,344評論 2 34
  • 41.多用派發(fā)隊列,少用同步鎖 在Objective-C中或颊,如果有多個線程要執(zhí)行同一份代碼,那么有時可能會出問題传于。...
    Code_Ninja閱讀 1,127評論 1 13
  • GCD調(diào)度隊列是執(zhí)行任務的強大工具囱挑。調(diào)度隊列允許您相對于調(diào)度者異步或者同步的執(zhí)行任意代碼塊。您能夠使用調(diào)度隊列來執(zhí)...
    坤坤同學閱讀 6,661評論 1 3